PolymerLabs/shady-css-parser

Name: shady-css-parser

Owner: PolymerLabs

Description: A fast, small and flexible CSS parser.

Created: 2015-08-26 05:18:33.0

Updated: 2018-03-01 11:38:41.0

Pushed: 2018-03-05 18:57:52.0

Homepage:

Size: 148

Language: TypeScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Shady CSS Parser

The motivation for Shady CSS Parser is to provide a fast, small and flexible CSS parser suitable for facilitating runtime parsing and transformation of CSS. The Polymer library and the Polymer Designer tool are both example cases where fast and flexible CSS parsing and transformation is a critical feature.

Goals
Installing

With node and npm installed, run the following command:

install shady-css-parser
Building

Run the following commands from the project root:

run build

This will create a dist directory containing distributable artifacts.

Usage
Basic parsing
rt * as shadyCss from 'shady-css-parser';
t css = 'body { color: red; }';
t parser = new shadyCss.Parser();
t ast = parser.parse(css);
Custom parsing
tep 1: Inherit from NodeFactory */
s CustomNodeFactory extends shadyCss.NodeFactory {


 Step 2: Implement a custom node factory method. Here we override the
   default factory for Expression nodes
/
pression(text) {
if (/^darken\(/.test(text)) {
  return {
    type: 'darkenExpression',
    color: text.replace(/^darken\(/, '').replace(/\)$/, ''),
  };
} else {
  return super.expression.apply(this, arguments);
}



t css = 'body { color: darken(red); }';
tep 3: Instantiate a Parser with an instance of the specialized
ustomNodeFactory */
t parser = new shadyCss.Parser(new CustomNodeFactory());
t ast = parser.parse(css);
Basic stringification
t stringifier = new shadyCss.Stringifier();
ngifier.stringify(ast);

Note: the built-in Parser and Stringifier discard most insignficiant whitespace from parsed CSS.

Custom stringification
tep 1: Inherit from Stringifier. */
s CustomStringifier extends shadyCss.Stringifier {

*
Step 2: Implement a stringification method named after the type of the node
you are interested in stringifying. In this case, we are implementing
stringification for the Darken Expression nodes we implemented parsing for
above.

rkenExpression(darkenExpression) {
// For the sake of brevity, please assume that the darken function returns
// a darker version of the color parameter:
return darken(darkenExpression.color);



tep 3: Use the custom stringifer: */
t stringifier = new CustomStringifier();
t css = stringifier.stringify(ast);
Example ASTs
Custom property declaration
tainer {
nog: blue;


ype": 1, /* stylesheet */
ules": [
{
  "type": 4, /* ruleset */
  "selector": ".container",
  "rulelist": {
    "type": 7, /* rulelist */
    "rules": [
      {
        "type": 6, /* declaration */
        "name": "--nog",
        "value": {
          "type": 5, /* expression */
          "text": "blue"
        }
      }
    ]
  }
}


Mixin declaration
set {
mixin-name: {
/* rules */



ype": 1, /* stylesheet */
ules": [
{
  "type": 4, /* ruleset */
  "selector": "ruleset",
  "rulelist": {
    "type": 7, /* rulelist */
    "rules": [
      {
        "type": 6, /* declaration */
        "name": "--mixin-name",
        "value": {
          "type": 7, /* rulelist */
          "rules": [
            {
              "type": 2, /* comment */
              "value": "\/* rules *\/"
            }
          ]
        }
      }
    ]
  }
}


Mixin application
le {
pply(--my-toolbar-title-theme);


ype": 1, /* stylesheet */
ules": [
{
  "type": 4, /* ruleset */
  "selector": ".title",
  "rulelist": {
    "type": 7, /* rulelist */
    "rules": [
      {
        "type": 3, /* at rule */
        "name": "apply",
        "parameters": "(--my-toolbar-title-theme)",
        "rulelist": null
      }
    ]
  }
}


Pathological comments
nclosed
 {
huk: {
/* buz */
baz: lur;



ype": 1, /* stylesheet */
ules": [
{
  "type": 2, /* comment */
  "value": "\/* unclosed\n@fiz {\n  --huk: {\n    \/* buz *\/"
},
{
  "type": 6, /* declaration */
  "name": "baz",
  "value": {
    "type": 5, /* expression */
    "text": "lur"
  }
},
{
  "type": 8, /* discarded */
  "text": "};\n"
},
{
  "type": 8, /* discarded */
  "text": "}"
}


Example stringification
Basic ruleset
efore */
 {
rgin: 0;
dding: 0px

fter */
{margin:0;padding:0px;}
At rules
efore */
ort url('foo.css');

t-face {
nt-family: foo;


rset 'foo';
fter */
ort url('foo.css');@font-face{font-family:foo;}@charset 'foo';
Custom properties
efore */
t {
qux: vim;
foo: {
bar: baz;



get {
k: var(--qux);
pply(--foo);

fter */
t{--qux:vim;--foo:{bar:baz;};}#target{gak:var(--qux);@apply (--foo);}

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.