// JS CSS
// Variables
var color = "#4d926f";
module.exports = {
"#header": {
color: color
}
, "h2": {
color: color
}
};
// Compiled CSS
#header {
color: #4d926f;
}
h2 {
color: #4d926f;
}
// Mixins
function roundedCorners (radius) {
radius || (radius = "5px");
return {
"-webkit-border-radius": radius
, "-moz-border-radius": radius
, "border-radius": radius
};
}
module.exports = {
"#header": roundedCorners()
, "#footer": roundedCorners("10px")
};
// Compiled CSS
#header {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
#footer {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
// Nested Rules
module.exports = {
"#header": {
"h1": {
"font-size": "26px"
, "font-weight": "bold"
}
, "p": {
"font-size": "12px"
, "a": {
"text-decoration": "none"
}
, "> .poop": {
"color": "brown"
}
}
}
};
// Compiled CSS
#header h1 {
font-size: 26px;
font-weight: bold;
}
#header p {
font-size: 12px;
}
#header p a {
text-decoration: none;
}
#header p a:hover {
border-width: 1px;
}
#header p > .poop {
color: brown;
}
// Functions and Operators
// Currently all I have is hex math
module.exports = {
".jibber-jabber": {
color: globals.baseColor
// Pretty stupid but whatever
, "background-color": hex.multiply(globals.baseColor, globals.accent, globals.backgroundColor)
}
}
// Animations, Media Queries, and Other More-Nested Features
module.exports = {
".columns": {
"display": "table"
, "width": "100%"
}
, ".columns > .column": {
"width": "50%"
, "box-sizing": "border-box"
, "margin-left": "20px"
}
, "@-animation-keyframes spin": {
"0%": {
"transform": "rotate(0deg)"
}
, "100%": {
"transform": "rotate(360deg)"
}
}
};
// Compiled CSS
/* ./layout.js*/
.columns {
display: table;
width: 100%;
}
.columns > .column {
width: 50%;
box-sizing: border-box;
margin-left: 20px;
}
@-animation-keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
// Make a jscss Build File
// It's just a javascript file you execute with node.js.
var jscss = require('jscss')
// Require your modules
, globals = require('./css/globals.js')
, layout = require('./css/layout.js')
, themes = require('./css/themes.js')
, main = require('./css/main.js')
;
// Compile your css
jscss(
// First parameter defines your output file
'./css/main.css'
// Subsequent parameters define modules to be compiled
, globals
, layout
, themes
, main
);
// Or just pass in the paths
jscss(
'./css/main.css'
, './css/globals.js'
, './css/layout.js'
, './css/themes.js'
, './css/main.js'
);
// Since this is all javascript, use a package manager.
// Organize your code into self-contained javascript modules. Easily include everything you'll need
// In the Browser
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="../lib/index.js"></script>
<script type="text/javascript">
// Mixin
function roundedCorners (radius{
radius || (radius = "5px");
return {
"-webkit-border-radius": radius
, "-moz-border-radius": radius
, "border-radius": radius
};
}
// Just a quick and dirty merge object
function mix (obj1, obj2) {
for (var key in obj2){
obj1[key] = obj2[key];
}
return obj1;
}
// Css declarations
var cssObj = {
"body": {
"background-color": "pink"
}
, ".testing": mix(
{
"background-color": "#fff"
, "padding": "22px"
, "> .test": {
"color": "blue"
}
}
, roundedCorners("10px")
)
};
// Embed the compiled jscss object
jscss.embed(jscss.compile(cssObj));
</script>
</head>
<body>
<div class="testing">
<span class="test">Just testing</span>
</div>
</body>
</html>
// JS CSS Source
// File index.js
;(function(){
var
id = 0
, indent = function(level){
var out = "";
for (var i = 0; i < level; i++){
out += " ";
}
return out
}
, _jscss = {
compile: function(obj){
var
selectors = {}
// Build nested rules into single rules
, _buildSelectors = function(hash, selector){
var curr, type, selector, key;
for (key in hash){
type = typeof (curr = hash[key]);
if (type == "string"){
if (!selectors[selector]) selectors[selector] = {};
selectors[selector][key] = curr;
}else if (type == "object"){
// Media query or animation or something
if (key[0] == "@"){
selectors[key] = curr;
}else{
_buildSelectors(curr, (selector ? (selector + " ") : "") + key);
}
}
}
}
// Take a flat css object and turn it into a string
, _compile = function(hash, level){
var spaces = " ", out = "", level = level || 0, curr;
for (var key in hash){
curr = hash[key];
out += indent(level) + key;
if (typeof curr == "object"){
out += " {\n" + _compile(curr, level + 1) + indent(level) + "}\n";
}else{
out += ": " + curr + ";\n";
}
}
return out;
}
;
_buildSelectors(obj, "");
return _compile(selectors, 0);
}
// Embeds a
, embed: function(styles, styleId){
if (typeof styles === "object") styles = _jscss(styles);
styleId || (styleId = "jscss-" + (id++));
var el = document.createElement('style');
el.type = "text/css";
el.rel = "stylesheet";
el.id = styleId;
el.innerHTML = "\n" + styles;
document.head.appendChild(el);
}
}
;
if (typeof define !== "undefined") {
define('jscss', function(){ return _jscss; });
}else if (typeof module !== "undefined" && module.exports){
module.exports = _jscss;
}else{
window.jscss = _jscss;
}
})();
// File jscss-old.js - заменен на index.js
var fs = require('fs');
var indent = function(level){
var out = "";
for (var i = 0; i < level; i++){
out += " ";
}
return out
};
// This is O(2s + 2d)
// Where s is the number of selectors
// And d is the number of properties
// I wonder if I can make it O(s + d)
var compile = function(obj){
var selectors = {},
// Make a predictable object we can work with
_buildSelectors = function(hash, selector){
var curr, type, selector, key;
for (key in hash){
type = typeof (curr = hash[key]);
if (type == "string"){
if (!selectors[selector]) selectors[selector] = {};
selectors[selector][key] = curr;
}else if (type == "object"){
// Media query or animation or something
if (key[0] == "@"){
selectors[key] = curr;
}else{
_buildSelectors(curr, (selector ? (selector + " ") : "") + key);
}
}
}
},
// Take a flat css object and turn it into a string
_compile = function(hash, level){
var spaces = " ", out = "", level = level || 0, curr;
for (var key in hash){
curr = hash[key];
out += indent(level) + key;
if (typeof curr == "object"){
out += " {\n" + _compile(curr, level + 1) + indent(level) + "}\n";
}else{
out += ": " + curr + ";\n";
}
}
return out;
};
_buildSelectors(obj, "");
// console.log(selectors);
return _compile(selectors, 0);
};
module.exports = function(output){
var stream = fs.createWriteStream(output);
var files = Array.prototype.slice.call(arguments, 1);
stream.once('open', function(){
for (var i = 0, file; i < files.length; i++){
file = require(files[i]);
stream.write('/* ' + files[i] + ' */\n\n');
stream.write(compile(file));
}
});
};
// File hex-math.js
var maxColor = 16777215
, colorToInt = function(hex){
hex = hex.replace('#', '');
// Change shorthand so we can do proper math
if (hex.length == 3){
var tmp = hex;
hex = "";
for (var i = 0; i < tmp.length; i++){
hex += "" + tmp[i] + tmp[i];
}
}
return ("0x" + hex - 0);
}
, intToColor = function(int){
int = int.toString(16);
while (int.length < 6){
int = "" + "0" + int;
}
return '#' + int;
}
, colorIntClamp = function(int){
if (int > maxColor) return maxColor;
if (int < 0) return 0;
return int;
}
;
module.exports = {
add: function(){
var args = Array.prototype.slice.call(arguments, 0), total = colorToInt(args[0]);
for (var i = 1; i < args.length; i++){
total += colorToInt(args[i]);
}
return colorIntClamp(intToColor(total));
}
, subtract: function(){
var args = Array.prototype.slice.call(arguments, 0), total = colorToInt(args[0]);
for (var i = 1; i < args.length; i++){
total += colorToInt(args[i]);
}
return colorIntClamp(intToColor(total));
}
, multiply: function(){
var args = Array.prototype.slice.call(arguments, 0), total = colorToInt(args[0]);
for (var i = 1; i < args.length; i++){
total *= colorToInt(args[i]);
}
return colorIntClamp(intToColor(total));
}
, divide: function(){
var args = Array.prototype.slice.call(arguments, 0), total = colorToInt(args[0]);
for (var i = 1; i < args.length; i++){
total /= colorToInt(args[i]);
}
return colorIntClamp(intToColor(total));
}
};
// Build example
// File build-jscss.js
var jscss = require('./jscss.js');
jscss(
'./style.css'
, './layout.js'
);
// File layout.js
module.exports = {
'.columns': {
'display': 'table'
, 'width': '100%'
}
, '.columns > .column': {
'width': '50%'
, 'box-sizing': 'border-box'
, 'margin-left': "20px"
}
, '#header': {
"h1": {
"font-size": "26px"
, "font-weight": "bold"
}
, "p": {
"font-size": "12px"
, "a": {
"text-decoration": "none"
// , "&:hover": { "border-width": "1px" }
}
, '> .poop': {
'color': 'brown'
}
}
, ".test": {
"font-size": "1.2rem"
}
}
, '@-animation-keyframes spin': {
'0%': {
'transform': 'rotate(0deg)'
}
, '100%': {
'transform': 'rotate(360deg)'
}
}
};
// File style.css
/* ./layout.js*/
.columns {
display: table;
width: 100%;
}
.columns > .column {
width: 50%;
box-sizing: border-box;
margin-left: 20px;
}
#header h1 {
font-size: 26px;
font-weight: bold;
}
#header p {
font-size: 12px;
}
#header p a {
text-decoration: none;
}
#header p > .poop {
color: brown;
}
#header .test {
font-size: 1.2rem;
}
@-animation-keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
Комментариев нет:
Отправить комментарий