Comparing version 0.0.36 to 0.0.37
@@ -5,3 +5,4 @@ var Absurd = (function(w) { | ||
helpers: {}, | ||
plugins: {} | ||
plugins: {}, | ||
processors: {} | ||
}; | ||
@@ -16,6 +17,20 @@ var require = function() { | ||
var extend = function(destination, source) { | ||
for (var key in source) { | ||
if (hasOwnProperty.call(source, key)) { | ||
destination[key] = source[key]; | ||
} | ||
} | ||
return destination; | ||
}; | ||
var _api = {}, | ||
_rules = {}, | ||
_storage = {}, | ||
_plugins = {}; | ||
_plugins = {}, | ||
_defaultOptions = { | ||
combineSelectors: true, | ||
minify: false, | ||
processor: lib.processors.CSS | ||
}; | ||
@@ -49,4 +64,5 @@ _api.getRules = function(stylesheet) { | ||
// client side specific methods | ||
_api.compile = function(callback) { | ||
lib.Processor( | ||
_api.compile = function(callback, options) { | ||
options = extend(_defaultOptions, options || {}); | ||
options.processor( | ||
_api.getRules(), | ||
@@ -80,110 +96,2 @@ callback || function() {}, | ||
} | ||
var cleanCSS = require('clean-css'), | ||
newline = '\n', | ||
defaultOptions = { | ||
combineSelectors: true, | ||
minify: false | ||
}; | ||
var toCSS = function(rules) { | ||
var css = ''; | ||
for(var selector in rules) { | ||
// handling raw content | ||
if(selector.indexOf("____raw") === 0) { | ||
css += rules[selector][selector] + newline; | ||
// handling normal styles | ||
} else { | ||
var entity = selector + ' {' + newline; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
entity += ' ' + transformUppercase(prop) + ': ' + rules[selector][prop] + ';' + newline; | ||
} | ||
entity += '}' + newline; | ||
css += entity; | ||
} | ||
} | ||
return css; | ||
} | ||
// dealing with false values | ||
var filterRules = function(rules) { | ||
var arr = {}; | ||
for(var selector in rules) { | ||
var areThereAnyProps = false; | ||
var props = {}; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
if(value !== false) { | ||
areThereAnyProps = true; | ||
props[prop] = value; | ||
} | ||
} | ||
if(areThereAnyProps) { | ||
arr[selector] = props; | ||
} | ||
} | ||
return arr; | ||
} | ||
// combining selectors | ||
var combineSelectors = function(rules) { | ||
var map = {}, | ||
arr = {}; | ||
// creating the map | ||
for(var selector in rules) { | ||
var props = rules[selector]; | ||
for(var prop in props) { | ||
var value = props[prop]; | ||
if(!map[prop]) map[prop] = {}; | ||
if(!map[prop][value]) map[prop][value] = []; | ||
map[prop][value].push(selector); | ||
} | ||
} | ||
// converting the map to usual rules object | ||
for(var prop in map) { | ||
var values = map[prop]; | ||
for(var value in values) { | ||
var selectors = values[value]; | ||
if(!arr[selectors.join(", ")]) arr[selectors.join(", ")] = {} | ||
var selector = arr[selectors.join(", ")]; | ||
selector[prop] = value; | ||
} | ||
} | ||
return arr; | ||
} | ||
// transform uppercase to [-lowercase] | ||
var transformUppercase = function(prop) { | ||
var transformed = ""; | ||
for(var i=0; c=prop.charAt(i); i++) { | ||
if(c === c.toUpperCase() && c.toLowerCase() !== c.toUpperCase()) { | ||
transformed += "-" + c.toLowerCase(); | ||
} else { | ||
transformed += c; | ||
} | ||
} | ||
return transformed; | ||
} | ||
lib.Processor = function(rules, callback, options) { | ||
options = options || defaultOptions; | ||
var css = ''; | ||
for(var stylesheet in rules) { | ||
var r = filterRules(rules[stylesheet]); | ||
r = options.combineSelectors ? combineSelectors(r) : r; | ||
if(stylesheet === "mainstream") { | ||
css += toCSS(r); | ||
} else { | ||
css += stylesheet + " {" + newline + toCSS(r) + "}" + newline; | ||
} | ||
} | ||
// Minification | ||
if(options.minify) { | ||
css = cleanCSS.process(css); | ||
if(callback) callback(null, css); | ||
} else { | ||
if(callback) callback(null, css); | ||
} | ||
return css; | ||
} | ||
lib.api.add = function(API) { | ||
@@ -356,13 +264,2 @@ var checkAndExecutePlugin = function(selector, prop, value, stylesheet) { | ||
} | ||
lib.helpers.PathFormatter = function(path) { | ||
var _path = {}; | ||
if(!path) { | ||
return false; | ||
} else if(typeof path == "string") { | ||
_path = {source: path}; | ||
} else { | ||
_path = path; | ||
} | ||
return _path; | ||
} | ||
lib.helpers.RequireUncached = function(module) { | ||
@@ -400,3 +297,3 @@ delete require.cache[require.resolve(module)] | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -432,3 +329,3 @@ // js or json | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -484,3 +381,3 @@ var content = '@media ' + value.media + " {\n"; | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -504,4 +401,112 @@ var content = '@supports ' + value.supports + " {\n"; | ||
} | ||
} | ||
var cleanCSS = require('clean-css'), | ||
newline = '\n', | ||
defaultOptions = { | ||
combineSelectors: true, | ||
minify: false | ||
}; | ||
var toCSS = function(rules) { | ||
var css = ''; | ||
for(var selector in rules) { | ||
// handling raw content | ||
if(selector.indexOf("____raw") === 0) { | ||
css += rules[selector][selector] + newline; | ||
// handling normal styles | ||
} else { | ||
var entity = selector + ' {' + newline; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
entity += ' ' + transformUppercase(prop) + ': ' + rules[selector][prop] + ';' + newline; | ||
} | ||
entity += '}' + newline; | ||
css += entity; | ||
} | ||
} | ||
return css; | ||
} | ||
// dealing with false values | ||
var filterRules = function(rules) { | ||
var arr = {}; | ||
for(var selector in rules) { | ||
var areThereAnyProps = false; | ||
var props = {}; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
if(value !== false) { | ||
areThereAnyProps = true; | ||
props[prop] = value; | ||
} | ||
} | ||
if(areThereAnyProps) { | ||
arr[selector] = props; | ||
} | ||
} | ||
return arr; | ||
} | ||
// combining selectors | ||
var combineSelectors = function(rules) { | ||
var map = {}, | ||
arr = {}; | ||
// creating the map | ||
for(var selector in rules) { | ||
var props = rules[selector]; | ||
for(var prop in props) { | ||
var value = props[prop]; | ||
if(!map[prop]) map[prop] = {}; | ||
if(!map[prop][value]) map[prop][value] = []; | ||
map[prop][value].push(selector); | ||
} | ||
} | ||
// converting the map to usual rules object | ||
for(var prop in map) { | ||
var values = map[prop]; | ||
for(var value in values) { | ||
var selectors = values[value]; | ||
if(!arr[selectors.join(", ")]) arr[selectors.join(", ")] = {} | ||
var selector = arr[selectors.join(", ")]; | ||
selector[prop] = value; | ||
} | ||
} | ||
return arr; | ||
} | ||
// transform uppercase to [-lowercase] | ||
var transformUppercase = function(prop) { | ||
var transformed = ""; | ||
for(var i=0; c=prop.charAt(i); i++) { | ||
if(c === c.toUpperCase() && c.toLowerCase() !== c.toUpperCase()) { | ||
transformed += "-" + c.toLowerCase(); | ||
} else { | ||
transformed += c; | ||
} | ||
} | ||
return transformed; | ||
} | ||
lib.processors.CSS = function(rules, callback, options) { | ||
options = options || defaultOptions; | ||
var css = ''; | ||
for(var stylesheet in rules) { | ||
var r = filterRules(rules[stylesheet]); | ||
r = options.combineSelectors ? combineSelectors(r) : r; | ||
if(stylesheet === "mainstream") { | ||
css += toCSS(r); | ||
} else { | ||
css += stylesheet + " {" + newline + toCSS(r) + "}" + newline; | ||
} | ||
} | ||
// Minification | ||
if(options.minify) { | ||
css = cleanCSS.process(css); | ||
if(callback) callback(null, css); | ||
} else { | ||
if(callback) callback(null, css); | ||
} | ||
return css; | ||
}; | ||
return client(); | ||
})(window); |
@@ -1,1 +0,1 @@ | ||
var Absurd=function(){function a(a,b){a=String(a).replace(/[^0-9a-f]/gi,""),a.length<6&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]),b=b||0;var c,d,e="#";for(d=0;3>d;d++)c=parseInt(a.substr(2*d,2),16),c=Math.round(Math.min(Math.max(0,c+c*b),255)).toString(16),e+=("00"+c).substr(c.length);return e}var b={api:{},helpers:{},plugins:{}},d=function(){},e=function(){return function(a){var c={},d={},e={},f={};c.getRules=function(a){return"undefined"==typeof a?d:("undefined"==typeof d[a]&&(d[a]=[]),d[a])},c.getPlugins=function(){return f},c.getStorage=function(){return e},c.flush=function(){d={},e=[]},c.numOfAddedRules=0,c.compile=function(a){b.Processor(c.getRules(),a||function(){},{combineSelectors:!0})},c.getPath=function(){return{}};for(var g in b.api)c[g]=b.api[g](c);for(var h in b.plugins)c.plugin(h,b.plugins[h]());return"function"==typeof a&&a(c),c}},f=d("clean-css"),g="\n",h={combineSelectors:!0,minify:!1},i=function(a){var b="";for(var c in a)if(0===c.indexOf("____raw"))b+=a[c][c]+g;else{var d=c+" {"+g;for(var e in a[c])a[c][e],d+=" "+l(e)+": "+a[c][e]+";"+g;d+="}"+g,b+=d}return b},j=function(a){var b={};for(var c in a){var d=!1,e={};for(var f in a[c]){var g=a[c][f];g!==!1&&(d=!0,e[f]=g)}d&&(b[c]=e)}return b},k=function(a){var b={},c={};for(var d in a){var e=a[d];for(var f in e){var g=e[f];b[f]||(b[f]={}),b[f][g]||(b[f][g]=[]),b[f][g].push(d)}}for(var f in b){var h=b[f];for(var g in h){var i=h[g];c[i.join(", ")]||(c[i.join(", ")]={});var d=c[i.join(", ")];d[f]=g}}return c},l=function(a){for(var b="",d=0;c=a.charAt(d);d++)b+=c===c.toUpperCase()&&c.toLowerCase()!==c.toUpperCase()?"-"+c.toLowerCase():c;return b};return b.Processor=function(a,b,c){c=c||h;var d="";for(var e in a){var l=j(a[e]);l=c.combineSelectors?k(l):l,d+="mainstream"===e?i(l):e+" {"+g+i(l)+"}"+g}return c.minify?(d=f.process(d),b&&b(null,d)):b&&b(null,d),d},b.api.add=function(a){var b=function(b,c,d,f){var g=a.getPlugins()[c];if("undefined"!=typeof g){var h=g(a,d);return h&&e(b,h,f),!0}return!1},c=function(b){var c=a.getPlugins();for(var d in b)"undefined"!=typeof c[d]&&(b[d]=!1);for(var d in b)":"===d.charAt(0)&&(b[d]=!1)},d=function(a,c,d){for(var f in c)"object"==typeof c[f]?(":"===f.charAt(0)?e(a+f,c[f],d):0===f.indexOf("@media")||0===f.indexOf("@supports")?e(a,c[f],f):b(a,f,c[f],d)===!1&&e(a+" "+f,c[f],d),c[f]=!1):b(a,f,c[f],d)&&(c[f]=!1)},e=function(f,g,h){if("undefined"==typeof g.length||"object"!=typeof g){if(!b(null,f,g,h)){if("object"==typeof a.getRules(h||"mainstream")[f]){var i=a.getRules(h||"mainstream")[f];for(var j in g)i[j]=g[j]}else a.getRules(h||"mainstream")[f]=g;d(f,g,h||"mainstream"),c(g)}}else for(var k=0;prop=g[k];k++)e(f,prop,h)},f=function(b,c){a.numOfAddedRules+=1;for(var d in b)if("undefined"!=typeof b[d].length&&"object"==typeof b[d])for(var f=0;r=b[d][f];f++)e(d,r,c||"mainstream");else e(d,b[d],c||"mainstream");return a};return f},b.api.colors=function(b){var c=b.darken=function(b,c){return a(b,-(c/100))},d=b.lighten=function(b,c){return a(b,c/100)};return{darken:c,lighten:d}},b.api.plugin=function(a){var b=function(b,c){return a.getPlugins()[b]=c,a};return b},b.api.raw=function(a){return function(b){var c={},d={},e="____raw_"+a.numOfAddedRules;return d[e]=b,c[e]=d,a.add(c),a}},b.api.storage=function(a){var b=a.getStorage(),c=function(c,d){if("undefined"==typeof d){if(b[c])return b[c];throw new Error("There is no data in the storage associated with '"+c+"'")}return b[c]=d,a};return c},b.helpers.PathFormatter=function(a){var b={};return a?b="string"==typeof a?{source:a}:a:!1},b.helpers.RequireUncached=function(a){return delete d.cache[d.resolve(a)],d(a)},b.plugins.charset=function(){return function(a,b){"string"==typeof b?a.raw('@charset: "'+b+'";'):"object"==typeof b&&(b=b.charset.replace(/:/g,"").replace(/'/g,"").replace(/"/g,"").replace(/ /g,""),a.raw('@charset: "'+b+'";'))}},b.plugins.document=function(){return function(a,b){if("object"==typeof b){var c="";if(c+="@"+b.vendor+"document",c+=" "+b.document,b.rules&&b.rules.length)for(var d=0;rule=b.rules[d];d++)a.handlecssrule(rule,c);else"undefined"!=typeof b.styles&&a.add(b.styles,c)}}},b.plugins.keyframes=function(){return function(a,b){var c=d(__dirname+"/../Processor");if("object"==typeof b)if("undefined"!=typeof b.frames){var e="@keyframes "+b.name+" {\n";e+=c({mainstream:b.frames}),e+="}",a.raw(e+"\n"+e.replace("@keyframes","@-webkit-keyframes"))}else if("undefined"!=typeof b.keyframes){for(var e="@keyframes "+b.name+" {\n",f={},g=0;rule=b.keyframes[g];g++)if("keyframe"===rule.type)for(var h=f[rule.values]={},i=0;declaration=rule.declarations[i];i++)"declaration"===declaration.type&&(h[declaration.property]=declaration.value);e+=c({mainstream:f}),e+="}",a.raw(e+"\n"+e.replace("@keyframes","@-webkit-keyframes"))}}},b.plugins.media=function(){return function(a,b){var c=d(__dirname+"/../Processor");if("object"==typeof b){for(var e="@media "+b.media+" {\n",f={},g=0;rule=b.rules[g];g++){var h=f[rule.selectors.toString()]={};if("rule"===rule.type)for(var i=0;declaration=rule.declarations[i];i++)"declaration"===declaration.type&&(h[declaration.property]=declaration.value)}e+=c({mainstream:f}),e+="}",a.raw(e)}}},b.plugins.namespace=function(){return function(a,b){"string"==typeof b?a.raw('@namespace: "'+b+'";'):"object"==typeof b&&(b=b.namespace.replace(/: /g,"").replace(/'/g,"").replace(/"/g,"").replace(/ /g,"").replace(/:h/g,"h"),a.raw('@namespace: "'+b+'";'))}},b.plugins.page=function(){return function(a,b){if("object"==typeof b){var c="";c+=b.selectors.length>0?"@page "+b.selectors.join(", ")+" {\n":"@page {\n";for(var d=0;declaration=b.declarations[d];d++)"declaration"==declaration.type&&(c+=" "+declaration.property+": "+declaration.value+";\n");c+="}",a.raw(c)}}},b.plugins.supports=function(){return function(a,b){var c=d(__dirname+"/../Processor");if("object"==typeof b){for(var e="@supports "+b.supports+" {\n",f={},g=0;rule=b.rules[g];g++){var h=f[rule.selectors.toString()]={};if("rule"===rule.type)for(var i=0;declaration=rule.declarations[i];i++)"declaration"===declaration.type&&(h[declaration.property]=declaration.value)}e+=c({mainstream:f}),e+="}",a.raw(e)}}},e()}(window); | ||
var Absurd=function(){function a(a,b){a=String(a).replace(/[^0-9a-f]/gi,""),a.length<6&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]),b=b||0;var c,d,e="#";for(d=0;3>d;d++)c=parseInt(a.substr(2*d,2),16),c=Math.round(Math.min(Math.max(0,c+c*b),255)).toString(16),e+=("00"+c).substr(c.length);return e}var b={api:{},helpers:{},plugins:{},processors:{}},d=function(){},e=function(){return function(a){var c=function(a,b){for(var c in b)hasOwnProperty.call(b,c)&&(a[c]=b[c]);return a},d={},e={},f={},g={},h={combineSelectors:!0,minify:!1,processor:b.processors.CSS};d.getRules=function(a){return"undefined"==typeof a?e:("undefined"==typeof e[a]&&(e[a]=[]),e[a])},d.getPlugins=function(){return g},d.getStorage=function(){return f},d.flush=function(){e={},f=[]},d.numOfAddedRules=0,d.compile=function(a,b){b=c(h,b||{}),b.processor(d.getRules(),a||function(){},{combineSelectors:!0})},d.getPath=function(){return{}};for(var i in b.api)d[i]=b.api[i](d);for(var j in b.plugins)d.plugin(j,b.plugins[j]());return"function"==typeof a&&a(d),d}};b.api.add=function(a){var b=function(b,c,d,f){var g=a.getPlugins()[c];if("undefined"!=typeof g){var h=g(a,d);return h&&e(b,h,f),!0}return!1},c=function(b){var c=a.getPlugins();for(var d in b)"undefined"!=typeof c[d]&&(b[d]=!1);for(var d in b)":"===d.charAt(0)&&(b[d]=!1)},d=function(a,c,d){for(var f in c)"object"==typeof c[f]?(":"===f.charAt(0)?e(a+f,c[f],d):0===f.indexOf("@media")||0===f.indexOf("@supports")?e(a,c[f],f):b(a,f,c[f],d)===!1&&e(a+" "+f,c[f],d),c[f]=!1):b(a,f,c[f],d)&&(c[f]=!1)},e=function(f,g,h){if("undefined"==typeof g.length||"object"!=typeof g){if(!b(null,f,g,h)){if("object"==typeof a.getRules(h||"mainstream")[f]){var i=a.getRules(h||"mainstream")[f];for(var j in g)i[j]=g[j]}else a.getRules(h||"mainstream")[f]=g;d(f,g,h||"mainstream"),c(g)}}else for(var k=0;prop=g[k];k++)e(f,prop,h)},f=function(b,c){a.numOfAddedRules+=1;for(var d in b)if("undefined"!=typeof b[d].length&&"object"==typeof b[d])for(var f=0;r=b[d][f];f++)e(d,r,c||"mainstream");else e(d,b[d],c||"mainstream");return a};return f},b.api.colors=function(b){var c=b.darken=function(b,c){return a(b,-(c/100))},d=b.lighten=function(b,c){return a(b,c/100)};return{darken:c,lighten:d}},b.api.plugin=function(a){var b=function(b,c){return a.getPlugins()[b]=c,a};return b},b.api.raw=function(a){return function(b){var c={},d={},e="____raw_"+a.numOfAddedRules;return d[e]=b,c[e]=d,a.add(c),a}},b.api.storage=function(a){var b=a.getStorage(),c=function(c,d){if("undefined"==typeof d){if(b[c])return b[c];throw new Error("There is no data in the storage associated with '"+c+"'")}return b[c]=d,a};return c},b.helpers.RequireUncached=function(a){return delete d.cache[d.resolve(a)],d(a)},b.plugins.charset=function(){return function(a,b){"string"==typeof b?a.raw('@charset: "'+b+'";'):"object"==typeof b&&(b=b.charset.replace(/:/g,"").replace(/'/g,"").replace(/"/g,"").replace(/ /g,""),a.raw('@charset: "'+b+'";'))}},b.plugins.document=function(){return function(a,b){if("object"==typeof b){var c="";if(c+="@"+b.vendor+"document",c+=" "+b.document,b.rules&&b.rules.length)for(var d=0;rule=b.rules[d];d++)a.handlecssrule(rule,c);else"undefined"!=typeof b.styles&&a.add(b.styles,c)}}},b.plugins.keyframes=function(){return function(a,b){var c=d(__dirname+"/../processors/CSS");if("object"==typeof b)if("undefined"!=typeof b.frames){var e="@keyframes "+b.name+" {\n";e+=c({mainstream:b.frames}),e+="}",a.raw(e+"\n"+e.replace("@keyframes","@-webkit-keyframes"))}else if("undefined"!=typeof b.keyframes){for(var e="@keyframes "+b.name+" {\n",f={},g=0;rule=b.keyframes[g];g++)if("keyframe"===rule.type)for(var h=f[rule.values]={},i=0;declaration=rule.declarations[i];i++)"declaration"===declaration.type&&(h[declaration.property]=declaration.value);e+=c({mainstream:f}),e+="}",a.raw(e+"\n"+e.replace("@keyframes","@-webkit-keyframes"))}}},b.plugins.media=function(){return function(a,b){var c=d(__dirname+"/../processors/CSS");if("object"==typeof b){for(var e="@media "+b.media+" {\n",f={},g=0;rule=b.rules[g];g++){var h=f[rule.selectors.toString()]={};if("rule"===rule.type)for(var i=0;declaration=rule.declarations[i];i++)"declaration"===declaration.type&&(h[declaration.property]=declaration.value)}e+=c({mainstream:f}),e+="}",a.raw(e)}}},b.plugins.namespace=function(){return function(a,b){"string"==typeof b?a.raw('@namespace: "'+b+'";'):"object"==typeof b&&(b=b.namespace.replace(/: /g,"").replace(/'/g,"").replace(/"/g,"").replace(/ /g,"").replace(/:h/g,"h"),a.raw('@namespace: "'+b+'";'))}},b.plugins.page=function(){return function(a,b){if("object"==typeof b){var c="";c+=b.selectors.length>0?"@page "+b.selectors.join(", ")+" {\n":"@page {\n";for(var d=0;declaration=b.declarations[d];d++)"declaration"==declaration.type&&(c+=" "+declaration.property+": "+declaration.value+";\n");c+="}",a.raw(c)}}},b.plugins.supports=function(){return function(a,b){var c=d(__dirname+"/../processors/CSS");if("object"==typeof b){for(var e="@supports "+b.supports+" {\n",f={},g=0;rule=b.rules[g];g++){var h=f[rule.selectors.toString()]={};if("rule"===rule.type)for(var i=0;declaration=rule.declarations[i];i++)"declaration"===declaration.type&&(h[declaration.property]=declaration.value)}e+=c({mainstream:f}),e+="}",a.raw(e)}}};var f=d("clean-css"),g="\n",h={combineSelectors:!0,minify:!1},i=function(a){var b="";for(var c in a)if(0===c.indexOf("____raw"))b+=a[c][c]+g;else{var d=c+" {"+g;for(var e in a[c])a[c][e],d+=" "+l(e)+": "+a[c][e]+";"+g;d+="}"+g,b+=d}return b},j=function(a){var b={};for(var c in a){var d=!1,e={};for(var f in a[c]){var g=a[c][f];g!==!1&&(d=!0,e[f]=g)}d&&(b[c]=e)}return b},k=function(a){var b={},c={};for(var d in a){var e=a[d];for(var f in e){var g=e[f];b[f]||(b[f]={}),b[f][g]||(b[f][g]=[]),b[f][g].push(d)}}for(var f in b){var h=b[f];for(var g in h){var i=h[g];c[i.join(", ")]||(c[i.join(", ")]={});var d=c[i.join(", ")];d[f]=g}}return c},l=function(a){for(var b="",d=0;c=a.charAt(d);d++)b+=c===c.toUpperCase()&&c.toLowerCase()!==c.toUpperCase()?"-"+c.toLowerCase():c;return b};return b.processors.CSS=function(a,b,c){c=c||h;var d="";for(var e in a){var l=j(a[e]);l=c.combineSelectors?k(l):l,d+="mainstream"===e?i(l):e+" {"+g+i(l)+"}"+g}return c.minify?(d=f.process(d),b&&b(null,d)):b&&b(null,d),d},e()}(window); |
var lib = { | ||
api: {}, | ||
helpers: {}, | ||
plugins: {} | ||
plugins: {}, | ||
processors: {} | ||
}; |
@@ -6,6 +6,20 @@ var client = function() { | ||
var extend = function(destination, source) { | ||
for (var key in source) { | ||
if (hasOwnProperty.call(source, key)) { | ||
destination[key] = source[key]; | ||
} | ||
} | ||
return destination; | ||
}; | ||
var _api = {}, | ||
_rules = {}, | ||
_storage = {}, | ||
_plugins = {}; | ||
_plugins = {}, | ||
_defaultOptions = { | ||
combineSelectors: true, | ||
minify: false, | ||
processor: lib.processors.CSS | ||
}; | ||
@@ -39,4 +53,5 @@ _api.getRules = function(stylesheet) { | ||
// client side specific methods | ||
_api.compile = function(callback) { | ||
lib.Processor( | ||
_api.compile = function(callback, options) { | ||
options = extend(_defaultOptions, options || {}); | ||
options.processor( | ||
_api.getRules(), | ||
@@ -43,0 +58,0 @@ callback || function() {}, |
@@ -1,109 +0,1 @@ | ||
var cleanCSS = require('clean-css'), | ||
newline = '\n', | ||
defaultOptions = { | ||
combineSelectors: true, | ||
minify: false | ||
}; | ||
var toCSS = function(rules) { | ||
var css = ''; | ||
for(var selector in rules) { | ||
// handling raw content | ||
if(selector.indexOf("____raw") === 0) { | ||
css += rules[selector][selector] + newline; | ||
// handling normal styles | ||
} else { | ||
var entity = selector + ' {' + newline; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
entity += ' ' + transformUppercase(prop) + ': ' + rules[selector][prop] + ';' + newline; | ||
} | ||
entity += '}' + newline; | ||
css += entity; | ||
} | ||
} | ||
return css; | ||
} | ||
// dealing with false values | ||
var filterRules = function(rules) { | ||
var arr = {}; | ||
for(var selector in rules) { | ||
var areThereAnyProps = false; | ||
var props = {}; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
if(value !== false) { | ||
areThereAnyProps = true; | ||
props[prop] = value; | ||
} | ||
} | ||
if(areThereAnyProps) { | ||
arr[selector] = props; | ||
} | ||
} | ||
return arr; | ||
} | ||
// combining selectors | ||
var combineSelectors = function(rules) { | ||
var map = {}, | ||
arr = {}; | ||
// creating the map | ||
for(var selector in rules) { | ||
var props = rules[selector]; | ||
for(var prop in props) { | ||
var value = props[prop]; | ||
if(!map[prop]) map[prop] = {}; | ||
if(!map[prop][value]) map[prop][value] = []; | ||
map[prop][value].push(selector); | ||
} | ||
} | ||
// converting the map to usual rules object | ||
for(var prop in map) { | ||
var values = map[prop]; | ||
for(var value in values) { | ||
var selectors = values[value]; | ||
if(!arr[selectors.join(", ")]) arr[selectors.join(", ")] = {} | ||
var selector = arr[selectors.join(", ")]; | ||
selector[prop] = value; | ||
} | ||
} | ||
return arr; | ||
} | ||
// transform uppercase to [-lowercase] | ||
var transformUppercase = function(prop) { | ||
var transformed = ""; | ||
for(var i=0; c=prop.charAt(i); i++) { | ||
if(c === c.toUpperCase() && c.toLowerCase() !== c.toUpperCase()) { | ||
transformed += "-" + c.toLowerCase(); | ||
} else { | ||
transformed += c; | ||
} | ||
} | ||
return transformed; | ||
} | ||
lib.Processor = function(rules, callback, options) { | ||
options = options || defaultOptions; | ||
var css = ''; | ||
for(var stylesheet in rules) { | ||
var r = filterRules(rules[stylesheet]); | ||
r = options.combineSelectors ? combineSelectors(r) : r; | ||
if(stylesheet === "mainstream") { | ||
css += toCSS(r); | ||
} else { | ||
css += stylesheet + " {" + newline + toCSS(r) + "}" + newline; | ||
} | ||
} | ||
// Minification | ||
if(options.minify) { | ||
css = cleanCSS.process(css); | ||
if(callback) callback(null, css); | ||
} else { | ||
if(callback) callback(null, css); | ||
} | ||
return css; | ||
} | ||
lib.api.add = function(API) { | ||
@@ -276,13 +168,2 @@ var checkAndExecutePlugin = function(selector, prop, value, stylesheet) { | ||
} | ||
lib.helpers.PathFormatter = function(path) { | ||
var _path = {}; | ||
if(!path) { | ||
return false; | ||
} else if(typeof path == "string") { | ||
_path = {source: path}; | ||
} else { | ||
_path = path; | ||
} | ||
return _path; | ||
} | ||
lib.helpers.RequireUncached = function(module) { | ||
@@ -320,3 +201,3 @@ delete require.cache[require.resolve(module)] | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -352,3 +233,3 @@ // js or json | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -404,3 +285,3 @@ var content = '@media ' + value.media + " {\n"; | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -424,2 +305,110 @@ var content = '@supports ' + value.supports + " {\n"; | ||
} | ||
} | ||
var cleanCSS = require('clean-css'), | ||
newline = '\n', | ||
defaultOptions = { | ||
combineSelectors: true, | ||
minify: false | ||
}; | ||
var toCSS = function(rules) { | ||
var css = ''; | ||
for(var selector in rules) { | ||
// handling raw content | ||
if(selector.indexOf("____raw") === 0) { | ||
css += rules[selector][selector] + newline; | ||
// handling normal styles | ||
} else { | ||
var entity = selector + ' {' + newline; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
entity += ' ' + transformUppercase(prop) + ': ' + rules[selector][prop] + ';' + newline; | ||
} | ||
entity += '}' + newline; | ||
css += entity; | ||
} | ||
} | ||
return css; | ||
} | ||
// dealing with false values | ||
var filterRules = function(rules) { | ||
var arr = {}; | ||
for(var selector in rules) { | ||
var areThereAnyProps = false; | ||
var props = {}; | ||
for(var prop in rules[selector]) { | ||
var value = rules[selector][prop]; | ||
if(value !== false) { | ||
areThereAnyProps = true; | ||
props[prop] = value; | ||
} | ||
} | ||
if(areThereAnyProps) { | ||
arr[selector] = props; | ||
} | ||
} | ||
return arr; | ||
} | ||
// combining selectors | ||
var combineSelectors = function(rules) { | ||
var map = {}, | ||
arr = {}; | ||
// creating the map | ||
for(var selector in rules) { | ||
var props = rules[selector]; | ||
for(var prop in props) { | ||
var value = props[prop]; | ||
if(!map[prop]) map[prop] = {}; | ||
if(!map[prop][value]) map[prop][value] = []; | ||
map[prop][value].push(selector); | ||
} | ||
} | ||
// converting the map to usual rules object | ||
for(var prop in map) { | ||
var values = map[prop]; | ||
for(var value in values) { | ||
var selectors = values[value]; | ||
if(!arr[selectors.join(", ")]) arr[selectors.join(", ")] = {} | ||
var selector = arr[selectors.join(", ")]; | ||
selector[prop] = value; | ||
} | ||
} | ||
return arr; | ||
} | ||
// transform uppercase to [-lowercase] | ||
var transformUppercase = function(prop) { | ||
var transformed = ""; | ||
for(var i=0; c=prop.charAt(i); i++) { | ||
if(c === c.toUpperCase() && c.toLowerCase() !== c.toUpperCase()) { | ||
transformed += "-" + c.toLowerCase(); | ||
} else { | ||
transformed += c; | ||
} | ||
} | ||
return transformed; | ||
} | ||
lib.processors.CSS = function(rules, callback, options) { | ||
options = options || defaultOptions; | ||
var css = ''; | ||
for(var stylesheet in rules) { | ||
var r = filterRules(rules[stylesheet]); | ||
r = options.combineSelectors ? combineSelectors(r) : r; | ||
if(stylesheet === "mainstream") { | ||
css += toCSS(r); | ||
} else { | ||
css += stylesheet + " {" + newline + toCSS(r) + "}" + newline; | ||
} | ||
} | ||
// Minification | ||
if(options.minify) { | ||
css = cleanCSS.process(css); | ||
if(callback) callback(null, css); | ||
} else { | ||
if(callback) callback(null, css); | ||
} | ||
return css; | ||
} |
47
index.js
#!/usr/bin/env node | ||
var PathFormatter = require("./lib/helpers/PathFormatter.js"), | ||
Processor = require("./lib/Processor.js"), | ||
cli = require('./lib/CLI.js'), | ||
var cli = require('./lib/CLI.js'), | ||
requireUncached = require('./lib/helpers/RequireUncached.js'); | ||
fs = require("fs"), | ||
argv = require('optimist').argv, | ||
_ = require("underscore"), | ||
hasOwnProperty = Object.prototype.hasOwnProperty, | ||
API = null, | ||
absurd = null, | ||
module.exports = absurd = function(path) { | ||
module.exports = absurd = function(func) { | ||
API = require("./lib/API.js")(); | ||
var _path = PathFormatter(path), | ||
_defaultOptions = { | ||
combineSelectors: true, | ||
minify: false | ||
}; | ||
var _defaultOptions = { | ||
combineSelectors: true, | ||
minify: false, | ||
processor: require("./lib/processors/CSS.js") | ||
}; | ||
var extend = function(destination, source) { | ||
for (var key in source) { | ||
if (hasOwnProperty.call(source, key)) { | ||
destination[key] = source[key]; | ||
} | ||
} | ||
return destination; | ||
}; | ||
// --------------------------------------------------- compile | ||
var compile = API.compile = function(callback, options) { | ||
options = _.extend(_defaultOptions, options || {}); | ||
if(typeof _path == "function") { | ||
_path(API); | ||
} else { | ||
if(_path !== false) { | ||
API.import(_path.source); | ||
} | ||
options = extend(_defaultOptions, options || {}); | ||
if(typeof func == "function") { | ||
func(API); | ||
} else if(typeof func == "string") { | ||
API.import(func); | ||
} | ||
Processor( | ||
options.processor( | ||
API.getRules(), | ||
_path.callback || callback || function() {}, | ||
callback || function() {}, | ||
options | ||
@@ -51,6 +56,2 @@ ); | ||
} | ||
// --------------------------------------------------- getPaths | ||
var getPath = API.getPath = function() { | ||
return _path; | ||
} | ||
@@ -57,0 +58,0 @@ return API; |
module.exports = function() { | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -5,0 +5,0 @@ // js or json |
module.exports = function() { | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -5,0 +5,0 @@ var content = '@media ' + value.media + " {\n"; |
module.exports = function() { | ||
return function(api, value) { | ||
var processor = require(__dirname + "/../Processor"); | ||
var processor = require(__dirname + "/../processors/CSS"); | ||
if(typeof value === "object") { | ||
@@ -5,0 +5,0 @@ var content = '@supports ' + value.supports + " {\n"; |
{ | ||
"name": "absurd", | ||
"version": "0.0.36", | ||
"version": "0.0.37", | ||
"homepage": "https://github.com/krasimir/absurd", | ||
@@ -13,3 +13,3 @@ "description": "CSS preprocessor", | ||
"license": "MIT", | ||
"dependencies": { | ||
"dependencies": { | ||
"optimist": "0.6.0", | ||
@@ -19,3 +19,2 @@ "colors": "0.6.2", | ||
"glob": "3.2.6", | ||
"underscore": "1.5.1", | ||
"css-parse": "1.5.3", | ||
@@ -22,0 +21,0 @@ "clean-css": "1.1.3" |
576
README.md
@@ -1,575 +0,13 @@ | ||
# absurd.js | ||
# AbsurdJS | ||
### Writing your CSS in JavaScript. That's it! | ||
### JavaScript based CSS preprocessor | ||
For AbsurdJS, the following code is valid CSS: | ||
AbsurdJS is a CSS preprocessor, which accepts JavaScript, JSON and CSS. It's available as [NodeJS module](http://krasimir.github.io/absurd/#server-side-usage) and also as [Client-side javascript library](http://krasimir.github.io/absurd/#client-side-usage). | ||
".navigation": { | ||
margin: "12px 0 0 0 ", | ||
type: "horizontal", | ||
a: { | ||
elementstyle: "button", | ||
responsive: "true" | ||
} | ||
} | ||
### Official site, documentation and online compilator | ||
*type*, *elementstyle* and *responsive* are just [plugins](https://github.com/krasimir/absurd#plugins) which return pure CSS. | ||
[http://krasimir.github.io/absurd/](http://krasimir.github.io/absurd/) | ||
====== | ||
### Resources | ||
- [Installation](#installation) | ||
- [Usage](#usage) | ||
- [Syntax](#syntax) | ||
- [API](#api) | ||
- [Testing](#testing) | ||
- Resources | ||
- In-depth article about AbsurdJS - [link](http://davidwalsh.name/write-css-javascript) | ||
====== | ||
## 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. | ||
### Compilation | ||
.compile([callback], [settings]) | ||
.compileFile([outputFile], [callback], [settings]) | ||
*settings* parameter is optional. Valid options: | ||
{ | ||
combineSelectors: true | false (by default true), | ||
minify: true | false (by default false) | ||
} | ||
#### Inline | ||
var Absurd = require("absurd"); | ||
Absurd(function(api) { | ||
// use the Absurd's api here | ||
}).compile(function(err, css) { | ||
// do something with the css | ||
}); | ||
#### To file | ||
var output = "./css/styles.css"; | ||
Absurd("./css/styles.js").compileFile(output, function(err, css) { | ||
// ... | ||
}); | ||
### Puting the styles in an external file | ||
#### .js | ||
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) { | ||
// ... | ||
}); | ||
#### .json | ||
The library supports importing of pure JSON. Of course this approach doesn't give you an access to the API, but it is still useful if you want to skip the typical Nodejs module definition. For example: | ||
// styles.json | ||
{ | ||
"body": { | ||
"margin": "0", | ||
"padding": "0", | ||
"fontSize": "1em", | ||
"p": { | ||
"line-height": "30px" | ||
} | ||
} | ||
} | ||
// app.js | ||
Absurd("styles.json").compile(function(err, css) { | ||
// ... | ||
}); | ||
#### .css | ||
Absurd accepts normal CSS. The good news is that you can still use all the other features. For example: | ||
// styles.js | ||
api.plugin("size", function(api, type) { | ||
switch(type) { | ||
case "large": return { fontSize: "30px" }; break; | ||
case "medium": return { fontSize: "24px" }; break; | ||
case "small": return { fontSize: "12px" }; break; | ||
default: return { fontSize: "16px" }; | ||
} | ||
}); | ||
api.import(__dirname + "/css/main.css"); | ||
// main.css | ||
body { | ||
margin-top: 10px; | ||
size: small; | ||
} | ||
And the result is: | ||
body { | ||
margin-top: 10px; | ||
font-size: 12px; | ||
} | ||
### 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] | ||
// Outputs the css to a file and watching specific directory. | ||
// If some of the files there is changed a compilation is fired. | ||
absurd -s [source file] -o [output file] -w [directory] | ||
// Minify the CSS | ||
absurd -s [source file] -m true | ||
### Using with Grunt | ||
Dependencies for your *package.json*: | ||
"dependencies": { | ||
"grunt": "~0.4.1", | ||
"grunt-contrib-watch": "*", | ||
"grunt-absurd": "*" | ||
} | ||
Simple *Gruntfile.js*: | ||
module.exports = function(grunt) { | ||
grunt.initConfig({ | ||
absurd: { | ||
task: { | ||
src: __dirname + "/css/absurd/index.js", | ||
dest: 'css/styles.css' | ||
} | ||
}, | ||
watch: { | ||
css: { | ||
files: ['css/absurd/**/*.js'], | ||
tasks: ['absurd'] | ||
} | ||
} | ||
}); | ||
grunt.loadNpmTasks('grunt-contrib-watch'); | ||
grunt.loadNpmTasks('grunt-absurd'); | ||
// grunt.registerTask('default', ['concat', 'less']); | ||
grunt.registerTask('default', ['absurd', 'watch']); | ||
} | ||
## 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: { | ||
marginTop: '20px', | ||
padding: 0, | ||
fontWeight: 'bold', | ||
section: { | ||
paddingTop: '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; | ||
} | ||
Have in mind that you don't need to quote the CSS properties. AbsurdJS converts every uppercase letter to a dash followed by the lowercase version of the letter. I.e.: | ||
WebkitTransform -> -webkit-transform | ||
You may send even an array of style like that | ||
{ | ||
'.header nav': [ | ||
{ fontSize: '10px' }, | ||
{ fontSize: '20px' } | ||
] | ||
} | ||
And that's compiled to | ||
.header nav { | ||
font-size: 20px; | ||
} | ||
### Pseudo classes | ||
It's similar like the example above: | ||
a: { | ||
textDecoration: 'none', | ||
color: '#000', | ||
':hover': { | ||
textDecoration: '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.json' | ||
]); | ||
api.import([ | ||
__dirname + '/forms/login-form.css', | ||
__dirname + '/forms/feedback-form.css' | ||
]); | ||
} | ||
Pay attention to the type of the files. The first two are actually JavaScript files, because they need an access to the API (to define mixins, plugins etc ...). The second *import* statement adds the actual styling. Of course it is not necessary to use this approach, but writing pure JSON sometimes may be a better option. | ||
### 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, | ||
fontSize: "10px" | ||
} | ||
}); | ||
} | ||
// B.js | ||
module.exports = function(api) { | ||
api.add({ | ||
'.header-button': [ | ||
api.storage("button")("#AAA", 10), | ||
{ | ||
color: '#F00', | ||
fontSize: '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. | ||
### Plugins (i.e. define your own CSS properties) | ||
The plugins are similar like mixins, but act as property-value pair. There is an API method for registering plugins. For example: | ||
api.plugin('my-custom-gradient', function(api, colors) { | ||
return { | ||
background: 'linear-gradient(to bottom, ' + colors.join(", ") + ')' | ||
}; | ||
}); | ||
api.plugin('brand-font-size', function(api, type) { | ||
switch(type) { | ||
case "small": return { fontSize: '12px'}; break; | ||
case "medium": return { fontSize: '22px'}; break; | ||
case "big": return { fontSize: '32px'}; break; | ||
default: return { fontSize: '12px'}; break; | ||
} | ||
}); | ||
The code creates two plugins, which respond on *my-custom-gradient* and *brand-font-size* property. So, the following styles | ||
api.add({ | ||
body: { | ||
margin: '20px', | ||
fontSize: '14px', | ||
'my-custom-gradient': ['#F00', '#00F'], | ||
p: { | ||
'brand-font-size': 'big' | ||
} | ||
} | ||
}); | ||
Are compiled to: | ||
body { | ||
margin: 20px; | ||
font-size: 14px; | ||
background: linear-gradient(to bottom, #F00, #00F); | ||
} | ||
body p { | ||
font-size: 32px; | ||
} | ||
Have in mind, that the plugin should always return an object. | ||
### Media queries | ||
The following code | ||
api.add({ | ||
body: { | ||
lineHeight: '20px', | ||
'@media all (max-width: 950px)': { | ||
lineHeight: '40px', | ||
color: '#BADA55' | ||
}, | ||
'@media all (min-width: 550px)': { | ||
lineHeight: '32px' | ||
}, | ||
p: { | ||
margin: '10px', | ||
padding: '4px', | ||
'@media all (max-width: 950px)': { | ||
padding: '12px', | ||
'brand-color': '' | ||
} | ||
} | ||
} | ||
}); | ||
is compiled to | ||
body { | ||
line-height: 20px; | ||
} | ||
body p { | ||
margin: 10px; | ||
padding: 4px; | ||
} | ||
@media all (max-width: 950px) { | ||
body { | ||
line-height: 40px; | ||
color: #BADA55; | ||
} | ||
body p { | ||
color: #9fA; | ||
padding: 12px; | ||
} | ||
} | ||
@media all (min-width: 550px) { | ||
body { | ||
line-height: 32px; | ||
} | ||
} | ||
### Sending raw data to the final compiled CSS | ||
AbsurdJS gives you ability to directly send content to the final CSS. I.e. something which is skipped by the compiler and it is directly concatenated with the processed data. | ||
api | ||
.add({ | ||
body: { | ||
marginTop: "20px", | ||
p: { | ||
fontSize: "5px" | ||
} | ||
} | ||
}) | ||
.raw('/* ' + comment + ' */') | ||
.add({ | ||
a: { | ||
paddingTop: "20px" | ||
} | ||
}); | ||
The code above is compiled to | ||
body { | ||
margin-top: 20px; | ||
} | ||
body p { | ||
font-size: 5px; | ||
} | ||
/* AbsurdJS is awesome! */ | ||
a { | ||
padding-top: 20px; | ||
} | ||
## API | ||
### .add([object]) | ||
module.exports = function(api) { | ||
api.add({ | ||
body: { | ||
padding: 0 | ||
} | ||
}); | ||
} | ||
### .import([string] | [[string, string, ...]]) | ||
module.exports = function(A) { | ||
A.import(__dirname + '/config/sizes.js'); | ||
A.import([ | ||
__dirname + '/config/colors.js', | ||
__dirname + '/config/sizes.js' | ||
]); | ||
} | ||
AbsurdJS supports importing of JavaScript, JSON and CSS files. | ||
### .storage([key], [value]) | ||
Setting value: | ||
module.exports = function(api) { | ||
api.storage("mixin", function(px) { | ||
return { | ||
fontSize: px + 'px' | ||
} | ||
}); | ||
} | ||
Getting value: | ||
module.exports = function(api) { | ||
api.add({ | ||
body: [ | ||
api.storage("mixin")(18) | ||
] | ||
}); | ||
} | ||
### .plugin([name of property], [function]) | ||
api.plugin('my-custom-gradient', function(api, colors) { | ||
return { | ||
background: 'linear-gradient(to bottom, ' + colors.join(", ") + ')' | ||
}; | ||
}); | ||
The function of the plugin accepts two arguments. The first one is a reference to the API and second one is the value of the CSS property. | ||
### .darken([color], [percents]) | ||
module.exports = function(api) { | ||
api.add({ | ||
body: { | ||
color: api.darken('#BADA55', 25) // darken 25% | ||
} | ||
}); | ||
} | ||
### .lighten([color], [percents]) | ||
module.exports = function(api) { | ||
api.add({ | ||
body: { | ||
color: api.lighten('#BADA55', 25) // lighten 25% | ||
} | ||
}); | ||
} | ||
### .raw([string]) | ||
module.exports = function(api) { | ||
api.raw('/* comment here */'); | ||
} | ||
## Testing | ||
The tests are placed in */tests* directory. Install [jasmine-node](https://github.com/mhevery/jasmine-node) and run | ||
jasmine ./tests | ||
- Article about AbsurdJS - [link](http://davidwalsh.name/write-css-javascript) |
@@ -17,18 +17,2 @@ describe("Absurd acting in code:", function() { | ||
it("should work with different path passing", function(done) { | ||
var path = ''; | ||
absurd = Absurd("./../data/css/index.js"); | ||
path = absurd.getPath(); | ||
expect(path.source).toBeDefined(); | ||
expect(path.source).toBe("./../data/css/index.js"); | ||
absurd = Absurd({source: "./../data/css/index.js"}); | ||
path = absurd.getPath(); | ||
expect(path.source).toBeDefined(); | ||
expect(path.source).toBe("./../data/css/index.js"); | ||
done(); | ||
}); | ||
it("should work with no path passed", function(done) { | ||
@@ -35,0 +19,0 @@ absurd = Absurd(); |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
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
6
205056
109
6158
13
- Removedunderscore@1.5.1
- Removedunderscore@1.5.1(transitive)