Skip to content

Commit 1741a7d

Browse files
author
Ivan Demidov
committedOct 8, 2015
init
0 parents  commit 1741a7d

File tree

10 files changed

+384
-0
lines changed

10 files changed

+384
-0
lines changed
 

‎.eslintrc

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"rules": {
3+
"no-unused-expressions": [0],
4+
"no-underscore-dangle": [0],
5+
"no-reserved-keys": [2],
6+
"no-multi-spaces": [0],
7+
"no-extra-parens": [0],
8+
"no-unused-vars": [2],
9+
"no-loop-func": [0],
10+
"key-spacing": [0],
11+
"max-len": [2],
12+
"strict": [0],
13+
"indent": [2],
14+
"quotes": [2, "single", "avoid-escape"],
15+
"curly": [0]
16+
},
17+
"env": {
18+
"mocha": true,
19+
"node": true
20+
}
21+
}

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

‎.npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

‎.travis.yml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
sudo: false
2+
language: node_js
3+
node_js:
4+
- iojs
5+
- "0.12"
6+
- "0.10"

‎LICENSE

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Scrum
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

‎README.md

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# PostCSS For Plugin
2+
[![Build Status](https://img.shields.io/travis/GitScrum/postcss-at-rules-variables.svg?style=flat-square)](https://travis-ci.org/GitScrum/postcss-at-rules-variables)
3+
[![npm version](https://img.shields.io/npm/v/postcss-at-rules-variables.svg?style=flat-square)](https://www.npmjs.com/package/postcss-at-rules-variables)
4+
[![npm downloads](https://img.shields.io/npm/dm/postcss-at-rules-variables.svg?style=flat-square)](https://www.npmjs.com/package/postcss-at-rules-variables)
5+
6+
Used in conjunction with the plugin [postcss-each], [postcss-conditionals], [postcss-for] and etc at-rules plugins.
7+
8+
9+
```css
10+
/* input.css */
11+
:root {
12+
--array: foo, bar, baz;
13+
--from: 1;
14+
--to: 3;
15+
--icon-exclude: 2;
16+
--color-danger: red;
17+
}
18+
19+
@each $val in var(--array) {
20+
@import "$val.css";
21+
}
22+
```
23+
24+
```css
25+
/* foo.css */
26+
html {
27+
background-color: var(--color-danger);
28+
}
29+
```
30+
31+
```css
32+
/* bar.css */
33+
.some-class {
34+
color: #fff;
35+
36+
@for $val from var(--from) to var(--to) {
37+
@if $val != var(--icon-exclude) {
38+
.icon-$val {
39+
background-position: 0 $(val)px;
40+
}
41+
}
42+
}
43+
}
44+
```
45+
46+
```css
47+
/* baz.css */
48+
h1 {
49+
font-size: 24px;
50+
}
51+
52+
@import "biz.css";
53+
```
54+
55+
```css
56+
/* biz.css */
57+
h2 {
58+
color: olive;
59+
}
60+
```
61+
62+
```css
63+
/* Output example */
64+
html {
65+
background-color: red;
66+
}
67+
.some-class {
68+
color: #fff;
69+
.icon-1 {
70+
background-position: 0 1px;
71+
}
72+
.icon-3 {
73+
background-position: 0 3px;
74+
}
75+
}
76+
h1 {
77+
font-size: 24px;
78+
}
79+
h2 {
80+
color: olive;
81+
}
82+
83+
```
84+
85+
## Installation
86+
87+
```console
88+
$ npm install postcss-at-rules-variables
89+
```
90+
91+
## Usage
92+
Use postcss-at-rules before you at-rules plugin
93+
94+
```js
95+
// dependencies
96+
var fs = require("fs");
97+
var postcss = require("postcss");
98+
var atImport = require("postcss-import");
99+
var atEach = require("postcss-each");
100+
var atVariables = require("postcss-at-rules-variables");
101+
var atIf = require('postcss-conditionals');
102+
var atFor = require('postcss-for');
103+
var customProperties = require("postcss-custom-properties");
104+
105+
106+
// css to be processed
107+
var css = fs.readFileSync("css/input.css", "utf8");
108+
109+
// process css
110+
var output = postcss()
111+
.use(atVariables({ /* options */ }))
112+
.use(atEach())
113+
.use(atImport({
114+
plugins: [
115+
require("postcss-at-rules-variables")({ /* options */ }),
116+
require("postcss-import"),
117+
]
118+
}))
119+
.use(atFor())
120+
.use(atIf())
121+
.use(customProperties())
122+
.process(css, {
123+
from: "css/input.css"
124+
})
125+
.css;
126+
127+
console.log(output);
128+
```
129+
130+
### Options
131+
132+
#### `atRules`
133+
134+
Type: `Array`
135+
Default: `['for', 'if', 'else', 'each']`
136+
137+
See [PostCSS](https://github.com/postcss/postcss) docs for examples for your environment.
138+
139+
[postcss-conditionals]: https://github.com/andyjansson/postcss-conditionals
140+
[postcss-each]: https://github.com/outpunk/postcss-each
141+
[postcss-for]: https://github.com/antyakushev/postcss-for

‎gulpfile.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
var gulp = require('gulp');
2+
var mocha = require('gulp-mocha');
3+
var eslint = require('gulp-eslint');
4+
5+
gulp.task('lint', function () {
6+
7+
return gulp.src(['index.js', 'test/*.js', 'gulpfile.js'])
8+
.pipe(eslint())
9+
.pipe(eslint.format())
10+
.pipe(eslint.failAfterError());
11+
});
12+
13+
gulp.task('test', function () {
14+
return gulp.src('test/*.js', { read: false })
15+
.pipe(mocha());
16+
});
17+
gulp.task('default', ['lint', 'test']);

‎index.js

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
var postcss = require('postcss');
2+
var balanced = require('balanced-match');
3+
var objectAssign = require('object-assign');
4+
5+
var VAR_FUNC_IDENTIFIER = 'var',
6+
maps = {};
7+
8+
function resolveValue(value) {
9+
10+
var start = value.indexOf(VAR_FUNC_IDENTIFIER + '(');
11+
12+
if (start === -1) {
13+
return [value];
14+
}
15+
16+
value.match(/var\(\S*\)/g).map(function(match){
17+
18+
19+
20+
var matches = balanced('(', ')', match);
21+
var reg = new RegExp(VAR_FUNC_IDENTIFIER + '.\(' + matches.body + '.\)', 'g');
22+
var property = maps[matches.body];
23+
24+
value = value.replace(reg, property);
25+
26+
});
27+
28+
return value;
29+
30+
}
31+
32+
module.exports = postcss.plugin('postcss-at-rules-variables', function(options) {
33+
34+
var DEFAULT = ({
35+
options: {
36+
atRules: ['for', 'if', 'else', 'each']
37+
},
38+
_concatRules: function(atRules){
39+
this.options.atRules = this.options.atRules.concat(atRules);
40+
return this.options;
41+
}
42+
}._concatRules(options && options.atRules || []));
43+
44+
options = objectAssign({}, options, DEFAULT);
45+
46+
47+
return function (css) {
48+
49+
var reg = new RegExp(options.atRules.join('|'));
50+
51+
css.walkRules(function(rule){
52+
if (rule.selectors[0] !== ':root') {
53+
return;
54+
}
55+
56+
rule.each(function(decl){
57+
var prop = decl.prop,
58+
value = decl.value;
59+
maps[prop] = value;
60+
});
61+
});
62+
63+
css.walkAtRules(reg, function(rules){
64+
rules.params = resolveValue(rules.params);
65+
});
66+
67+
};
68+
});

‎package.json

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name": "postcss-at-rules-variables",
3+
"version": "0.0.0",
4+
"description": "PostCss plugin to use CSS Custom Properties in at-rule @each, @for, @if, @else ",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "gulp"
8+
},
9+
"keywords": [
10+
"postcss",
11+
"css",
12+
"postcss-plugin",
13+
"for",
14+
"if",
15+
"else",
16+
"each",
17+
"at-rules",
18+
"property"
19+
],
20+
"repository": {
21+
"type": "git",
22+
"url": "https://github.com/GitScrum/postcss-at-rules-variables.git"
23+
},
24+
"author": {
25+
"name": "Scrum"
26+
},
27+
"license": "MIT",
28+
"dependencies": {
29+
"balanced-match": "^0.2.0",
30+
"object-assign": "^4.0.1",
31+
"postcss": "^5.0.6"
32+
},
33+
"devDependencies": {
34+
"chai": "3.2.0",
35+
"gulp": "3.9.0",
36+
"gulp-eslint": "0.11.1",
37+
"gulp-mocha": "2.1.3"
38+
},
39+
"bugs": {
40+
"url": "https://github.com/gitscrum/postcss-at-rules-variables/issues"
41+
},
42+
"homepage": "https://github.com/gitscrum/postcss-at-rules-variables#readme"
43+
}

‎test/test.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
var postcss = require('postcss');
2+
var expect = require('chai').expect;
3+
4+
var plugin = require('../');
5+
6+
var test = function (input, output, opts) {
7+
expect(postcss([plugin(opts) ]).process(input).css).to.eql(output);
8+
};
9+
10+
describe('postcss-at-rules-variables', function () {
11+
12+
it('it change first properties for @for', function(){
13+
test(
14+
':root{ --from: 1; } @for $i from var(--from) to 2',
15+
':root{ --from: 1; } @for $i from 1 to 2'
16+
);
17+
});
18+
19+
it('it change second properties for @for', function(){
20+
test(
21+
':root{ --to: 2; } @for $i from 1 to var(--to)',
22+
':root{ --to: 2; } @for $i from 1 to 2'
23+
);
24+
});
25+
26+
it('it change two properties for @for', function(){
27+
test(
28+
':root{ --from: 1; --to: 2; } @for $i from var(--from) to var(--to)',
29+
':root{ --from: 1; --to: 2; } @for $i from 1 to 2'
30+
);
31+
});
32+
33+
it('it change three properties for @for', function(){
34+
test(
35+
':root{ --from: 1; --to: 2; --step: 5 } @for $i from var(--from) to var(--to) by var(--step)',
36+
':root{ --from: 1; --to: 2; --step: 5 } @for $i from 1 to 2 by 5'
37+
);
38+
});
39+
40+
it('it change two properties for @if', function(){
41+
test(
42+
':root{ --first: 1; --second: 2; } @if var(--first) < var(--second)',
43+
':root{ --first: 1; --second: 2; } @if 1 < 2',
44+
{ atRules: ['if'] }
45+
);
46+
});
47+
48+
it('it change two properties for @if, @else if', function(){
49+
test(
50+
':root{ --first: 1; --second: 2; } @if var(--first) < var(--second) { color: olive; } @else if var(--first) > var(--second) { color: red; }',
51+
':root{ --first: 1; --second: 2; } @if 1 < 2 { color: olive; } @else if 1 > 2 { color: red; }',
52+
{ atRules: ['if', 'else'] }
53+
);
54+
});
55+
56+
it('it change multi properties for @each', function(){
57+
test(
58+
':root{ --array: foo, bar, baz; } @each $val in var(--array)',
59+
':root{ --array: foo, bar, baz; } @each $val in foo, bar, baz',
60+
{ atRules: ['each'] }
61+
);
62+
});
63+
64+
});

0 commit comments

Comments
 (0)
Please sign in to comment.