среда, 27 июля 2016 г.

JavaScript CSS

// 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);
  }
}

Комментариев нет:

Отправить комментарий