UNPKG

5.06 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.7.0
2(function() {
3 var CleanCSS, RootsUtil, crypto, fs, minimatch, path, yaml, _;
4
5 fs = require('fs');
6
7 path = require('path');
8
9 _ = require('lodash');
10
11 minimatch = require('minimatch');
12
13 CleanCSS = require('clean-css');
14
15 crypto = require('crypto');
16
17 RootsUtil = require('roots-util');
18
19 yaml = require('js-yaml');
20
21 module.exports = function(opts) {
22 var CSSPipeline;
23 opts = _.defaults(opts, {
24 files: 'assets/css/**',
25 manifest: false,
26 out: false,
27 minify: false,
28 hash: false,
29 opts: {}
30 });
31 opts.files = Array.prototype.concat(opts.files);
32 return CSSPipeline = (function() {
33
34 /**
35 * Sets up the custom category and view function.
36 * The view function grabs either the single output path or collects
37 * all non-ignored output paths for the input files and returns them
38 * as html link tags.
39 *
40 * @param {Function} @roots - Roots class instance
41 */
42 var get_output_paths, load_manifest_file;
43
44 function CSSPipeline(roots) {
45 var _base;
46 this.roots = roots;
47 this.category = 'css-pipeline';
48 this.file_map = {};
49 this.util = new RootsUtil(this.roots);
50 if (opts.manifest) {
51 this.roots.config.ignores.push(opts.manifest);
52 this.manifest = load_manifest_file.call(this, opts.manifest);
53 }
54 this.files = this.manifest || opts.files;
55 if ((_base = this.roots.config).locals == null) {
56 _base.locals = {};
57 }
58 this.roots.config.locals.css = (function(_this) {
59 return function() {
60 var matcher, paths, _i, _len, _ref;
61 paths = [];
62 if (opts.out) {
63 paths.push(opts.out);
64 } else {
65 _ref = _this.files;
66 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
67 matcher = _ref[_i];
68 paths = paths.concat(get_output_paths.call(_this, matcher));
69 }
70 }
71 return paths.map(function(p) {
72 return "<link rel='stylesheet' href='/" + p + "' />";
73 }).join("\n");
74 };
75 })(this);
76 }
77
78
79 /**
80 * Minimatch runs against each path, quick and easy.
81 */
82
83 CSSPipeline.prototype.fs = function() {
84 return {
85 extract: true,
86 detect: (function(_this) {
87 return function(f) {
88 return _.any(_this.files, minimatch.bind(_this, f.relative));
89 };
90 })(this)
91 };
92 };
93
94
95 /**
96 * After compile, if concat is happening, grab the contents and save them
97 * away, then prevent write.
98 */
99
100 CSSPipeline.prototype.compile_hooks = function() {
101 return {
102 write: function() {
103 return !opts.out;
104 },
105 after_file: (function(_this) {
106 return function(ctx) {
107 if (opts.out) {
108 return _this.file_map[ctx.file.relative] = ctx.content;
109 }
110 };
111 })(this)
112 };
113 };
114
115
116 /**
117 * Write the output file if necessary.
118 */
119
120 CSSPipeline.prototype.category_hooks = function() {
121 return {
122 after: (function(_this) {
123 return function(ctx) {
124 var all_contents, content, file, hash, matcher, res, _i, _len, _ref, _ref1;
125 if (!opts.out) {
126 return;
127 }
128 all_contents = '';
129 _ref = _this.files;
130 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
131 matcher = _ref[_i];
132 _ref1 = _this.file_map;
133 for (file in _ref1) {
134 content = _ref1[file];
135 if (minimatch(file, matcher)) {
136 all_contents += content;
137 }
138 }
139 }
140 if (opts.minify) {
141 all_contents = (new CleanCSS(opts.opts)).minify(all_contents);
142 }
143 if (opts.hash) {
144 hash = crypto.createHash('md5').update(all_contents, 'utf8');
145 res = opts.out.split('.');
146 res.splice(-1, 0, hash.digest('hex'));
147 opts.out = res.join('.');
148 }
149 return _this.util.write(opts.out, all_contents);
150 };
151 })(this)
152 };
153 };
154
155
156 /**
157 * @private
158 */
159
160 load_manifest_file = function(f) {
161 var res;
162 res = yaml.safeLoad(fs.readFileSync(path.join(this.roots.root, f), 'utf8'));
163 return res.map(function(m) {
164 return path.join(path.dirname(f), m);
165 });
166 };
167
168 get_output_paths = function(files) {
169 return this.util.files(files).map((function(_this) {
170 return function(f) {
171 return path.sep + _this.util.output_path(f.relative, 'css').relative;
172 };
173 })(this));
174 };
175
176 return CSSPipeline;
177
178 })();
179 };
180
181}).call(this);