Skip to content

Commit 0bfe5bb

Browse files
authored
Merge pull request #42 from suitcss/transform-and-onimport
Allow usage of transform and onImport options
2 parents 6be3f85 + 61d5360 commit 0bfe5bb

File tree

5 files changed

+131
-14
lines changed

5 files changed

+131
-14
lines changed

.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"extends": "airbnb/legacy",
3+
"globals": {
4+
"Promise": true
5+
},
36
"rules": {
47
"vars-on-top": 0,
58
"no-console": 0,

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### HEAD
22

3+
* Allow usage of `transform` and `onImport` in `postcss-easy-import`
34
* Remove `beforeLint` feature
45
* Add default browsers list for autoprefixer
56
* Use `stylelint-config-suitcss` from within the preprocessor. No longer needs

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Examples:
6969

7070
### Node.js
7171

72-
Returns a [PostCSS promise](https://github.com/postcss/postcss/blob/master/docs/api.md#lazyresult-class)
72+
Returns a [PostCSS promise](http://api.postcss.org/LazyResult.html)
7373

7474
```js
7575
var preprocessor = require('suitcss-preprocessor');
@@ -131,7 +131,7 @@ If set to `true` then the output is minified by [`cssnano`](http://cssnano.co/).
131131
* Type: `Object`
132132
* Default: `undefined`
133133

134-
Options that are passed directly to `postcss`, as per [the documentation](https://github.com/postcss/postcss/blob/master/docs/api.md#processorprocesscss-opts).
134+
Options that are passed directly to `postcss`, as per [the documentation](http://api.postcss.org/global.html#processOptions).
135135

136136
```js
137137
{
@@ -195,7 +195,7 @@ Options are merged recursively with the defaults. For example, adding new plugin
195195

196196
By default the preprocessor uses all necessary plugins to build SUIT components. However additional plugins can be installed into a project and then added to the `use` array.
197197

198-
**Note**: This will not work with the preprocessor installed globally. Instead rely on the convenience of `npm run <script>`
198+
**Note**: This will not work with the preprocessor installed globally. Instead rely on the convenience of `npm run script`
199199

200200
```js
201201
module.exports = {

lib/index.js

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,8 @@ var defaults = {
3030
'ios > 6, android > 4.3, samsung > 3, chromeandroid > 50'
3131
},
3232
'postcss-easy-import': {
33-
onImport: function(imported) {
34-
// Update the watch task with the list of imported files
35-
if (typeof global.watchCSS === 'function') {
36-
global.watchCSS(imported);
37-
}
38-
}
33+
transform: identity,
34+
onImport: noop
3935
},
4036
'postcss-reporter': {
4137
clearMessages: true
@@ -49,7 +45,6 @@ var defaults = {
4945
}
5046
};
5147

52-
5348
/**
5449
* Process CSS
5550
*
@@ -86,18 +81,26 @@ function preprocessor(css, options) {
8681
function mergeOptions(options) {
8782
options = options || {};
8883
var mergedOpts = assign({}, defaults, options);
84+
var easyImportOpts = mergedOpts['postcss-easy-import'];
85+
var origTransform = easyImportOpts.transform;
86+
var origOnImport = easyImportOpts.onImport;
8987

90-
// Set some core options
9188
if (mergedOpts.root) {
92-
mergedOpts['postcss-easy-import'].root = mergedOpts.root;
89+
easyImportOpts.root = mergedOpts.root;
9390
}
9491

95-
mergedOpts['postcss-easy-import'].transform = function(css, filename) {
96-
return lintImportedFiles(mergedOpts, css, filename).then(function(result) {
92+
easyImportOpts.transform = function(css, filename) {
93+
var transformedCss = origTransform(css);
94+
return lintImportedFiles(mergedOpts, transformedCss, filename).then(function(result) {
9795
return result.css;
9896
});
9997
};
10098

99+
easyImportOpts.onImport = function(importedFiles) {
100+
updateWatchTaskFiles(importedFiles);
101+
origOnImport(importedFiles);
102+
};
103+
101104
// Allow additional plugins to be merged with the defaults
102105
// but remove any duplicates so that it respects the new order
103106
if (!isEmpty(options.use)) {
@@ -126,5 +129,27 @@ function lintImportedFiles(options, css, filename) {
126129
.use(bemLinter(options['postcss-bem-linter']))
127130
.use(reporter(options['postcss-reporter']));
128131

132+
if (isPromise(css)) {
133+
return css.then(function(css) { // eslint-disable-line no-shadow
134+
return processor.process(css, {from: filename});
135+
});
136+
}
137+
129138
return processor.process(css, {from: filename});
130139
}
140+
141+
function isPromise(obj) {
142+
return typeof obj.then === 'function';
143+
}
144+
145+
function noop() {}
146+
147+
function identity(x) {
148+
return x;
149+
}
150+
151+
function updateWatchTaskFiles(files) {
152+
if (typeof global.watchCSS === 'function') {
153+
global.watchCSS(files);
154+
}
155+
}

test/test.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,94 @@ describe('suitcss', function() {
121121
});
122122
});
123123

124+
describe('using the transform option in postcss-import', function() {
125+
it('should use a default transform function that just returns the css', function(done) {
126+
suitcss('@import "./util.css";', {
127+
lint: true,
128+
root: 'test/fixtures'
129+
}).then(function(result) {
130+
expect(result.css).to.equal('.u-img {\n border-radius: 50%;\n}');
131+
done();
132+
})
133+
.catch(done);
134+
});
135+
136+
it('should call a custom transform function with the imported component', function(done) {
137+
var transformStub = sinon.stub().returns('body { color: blue; }');
138+
139+
suitcss('@import "./util.css";', {
140+
lint: true,
141+
root: 'test/fixtures',
142+
'postcss-easy-import': {
143+
transform: transformStub
144+
}
145+
}).then(function(result) {
146+
expect(transformStub.calledOnce).to.be.true;
147+
expect(transformStub.getCall(0).args[0]).to.equal('.u-img {\n border-radius: 50%;\n}\n');
148+
expect(result.css).to.equal('body { color: blue; }');
149+
done();
150+
})
151+
.catch(done);
152+
});
153+
154+
it('should also work with a promise returned from the custom transform function', function(done) {
155+
suitcss('@import "./util.css";', {
156+
lint: true,
157+
root: 'test/fixtures',
158+
'postcss-easy-import': {
159+
transform: function() {
160+
return Promise.resolve('body { font: red; }');
161+
}
162+
}
163+
}).then(function(result) {
164+
expect(result.css).to.equal('body { font: red; }');
165+
done();
166+
})
167+
.catch(done);
168+
});
169+
});
170+
171+
describe('using the onImport option postcss-import', function() {
172+
var updateWatchTaskFilesSpy, revert;
173+
174+
beforeEach(function() {
175+
updateWatchTaskFilesSpy = sinon.spy();
176+
revert = suitcss.__set__('updateWatchTaskFiles', updateWatchTaskFilesSpy);
177+
});
178+
179+
afterEach(function() {
180+
revert();
181+
});
182+
183+
it('should call the updateWatchTaskFiles function with the file paths', function(done) {
184+
suitcss('@import "./util.css";', {
185+
lint: true,
186+
root: 'test/fixtures'
187+
}).then(function() {
188+
expect(updateWatchTaskFilesSpy.getCall(0).args[0][0]).to.contain('util.css');
189+
done();
190+
})
191+
.catch(done);
192+
});
193+
194+
it('should call a custom onImport function', function(done) {
195+
var onImportSpy = sinon.spy();
196+
197+
suitcss('@import "./util.css";', {
198+
lint: true,
199+
root: 'test/fixtures',
200+
'postcss-easy-import': {
201+
onImport: onImportSpy
202+
}
203+
}).then(function() {
204+
expect(onImportSpy.getCall(0).args[0][0]).to.contain('util.css');
205+
expect(updateWatchTaskFilesSpy.getCall(0).args[0][0]).to.contain('util.css');
206+
done();
207+
})
208+
.catch(done);
209+
});
210+
});
211+
124212
describe('re-ordering plugins', function() {
125213
it('should allow reordering of use array and remove duplicates', function() {
126214
var opts = mergeOptions({

0 commit comments

Comments
 (0)