UNPKG

5.32 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.9.1
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(prefix) {
60 var i, len, matcher, paths, ref;
61 if (prefix == null) {
62 prefix = '';
63 }
64 paths = [];
65 if (opts.out) {
66 paths.push("" + prefix + opts.out);
67 } else {
68 ref = _this.files;
69 for (i = 0, len = ref.length; i < len; i++) {
70 matcher = ref[i];
71 paths = paths.concat(get_output_paths.call(_this, matcher, prefix));
72 }
73 }
74 return paths.map(function(p) {
75 return "<link rel='stylesheet' href='" + p + "' />";
76 }).join("\n");
77 };
78 })(this);
79 }
80
81
82 /**
83 * Minimatch runs against each path, quick and easy.
84 */
85
86 CSSPipeline.prototype.fs = function() {
87 return {
88 extract: true,
89 detect: (function(_this) {
90 return function(f) {
91 return _.any(_this.files, minimatch.bind(_this, f.relative));
92 };
93 })(this)
94 };
95 };
96
97
98 /**
99 * After compile, if concat is happening, grab the contents and save them
100 * away, then prevent write.
101 */
102
103 CSSPipeline.prototype.compile_hooks = function() {
104 return {
105 write: function() {
106 return !opts.out;
107 },
108 after_file: (function(_this) {
109 return function(ctx) {
110 if (opts.out) {
111 return _this.file_map[ctx.file.relative] = ctx.content;
112 }
113 };
114 })(this)
115 };
116 };
117
118
119 /**
120 * Write the output file if necessary.
121 */
122
123 CSSPipeline.prototype.category_hooks = function() {
124 return {
125 after: (function(_this) {
126 return function(ctx) {
127 var all_contents, content, file, hash, i, len, matcher, ref, ref1, res;
128 if (!opts.out) {
129 return;
130 }
131 all_contents = '';
132 ref = _this.files;
133 for (i = 0, len = ref.length; i < len; i++) {
134 matcher = ref[i];
135 ref1 = _this.file_map;
136 for (file in ref1) {
137 content = ref1[file];
138 if (minimatch(file, matcher)) {
139 all_contents += content;
140 }
141 }
142 }
143 if (opts.minify) {
144 all_contents = (new CleanCSS(opts.opts)).minify(all_contents).toString();
145 }
146 if (opts.hash) {
147 hash = crypto.createHash('md5').update(all_contents, 'utf8');
148 res = opts.out.split('.');
149 res.splice(-1, 0, hash.digest('hex'));
150 opts.out = res.join('.');
151 }
152 return _this.util.write(opts.out, all_contents);
153 };
154 })(this)
155 };
156 };
157
158
159 /**
160 * @private
161 */
162
163 load_manifest_file = function(f) {
164 var res;
165 res = yaml.safeLoad(fs.readFileSync(path.join(this.roots.root, f), 'utf8'));
166 return res.map(function(m) {
167 return path.join(path.dirname(f), m);
168 });
169 };
170
171 get_output_paths = function(files, prefix) {
172 return this.util.files(files).map((function(_this) {
173 return function(f) {
174 var fN, filePath;
175 filePath = _this.util.output_path(f.relative).relative;
176 fN = path.join(prefix, filePath.replace(path.extname(filePath), '.css'));
177 return fN.replace(new RegExp('\\' + path.sep, 'g'), '/');
178 };
179 })(this));
180 };
181
182 return CSSPipeline;
183
184 })();
185 };
186
187}).call(this);