Initial commit
[yaffs-website] / node_modules / gulp-sass / index.js
1 'use strict';
2
3 var gutil = require('gulp-util');
4 var through = require('through2');
5 var clonedeep = require('lodash.clonedeep');
6 var path = require('path');
7 var applySourceMap = require('vinyl-sourcemaps-apply');
8
9 var PLUGIN_NAME = 'gulp-sass';
10
11 //////////////////////////////
12 // Main Gulp Sass function
13 //////////////////////////////
14 var gulpSass = function gulpSass(options, sync) {
15   return through.obj(function(file, enc, cb) {
16     var opts,
17         filePush,
18         errorM,
19         callback,
20         result;
21
22     if (file.isNull()) {
23       return cb(null, file);
24     }
25     if (file.isStream()) {
26       return cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
27     }
28     if (path.basename(file.path).indexOf('_') === 0) {
29       return cb();
30     }
31     if (!file.contents.length) {
32       file.path = gutil.replaceExtension(file.path, '.css');
33       return cb(null, file);
34     }
35
36
37     opts = clonedeep(options || {});
38     opts.data = file.contents.toString();
39
40     // we set the file path here so that libsass can correctly resolve import paths
41     opts.file = file.path;
42
43     // Ensure `indentedSyntax` is true if a `.sass` file
44     if (path.extname(file.path) === '.sass') {
45       opts.indentedSyntax = true;
46     }
47
48     // Ensure file's parent directory in the include path
49     if (opts.includePaths) {
50       if (typeof opts.includePaths === 'string') {
51         opts.includePaths = [opts.includePaths];
52       }
53     }
54     else {
55       opts.includePaths = [];
56     }
57
58     opts.includePaths.unshift(path.dirname(file.path));
59
60     // Generate Source Maps if plugin source-map present
61     if (file.sourceMap) {
62       opts.sourceMap = file.path;
63       opts.omitSourceMapUrl = true;
64       opts.sourceMapContents = true;
65     }
66
67     //////////////////////////////
68     // Handles returning the file to the stream
69     //////////////////////////////
70     filePush = function filePush(sassObj) {
71       var sassMap,
72           sassMapFile,
73           sassFileSrc,
74           sassFileSrcPath,
75           sourceFileIndex;
76
77       // Build Source Maps!
78       if (sassObj.map) {
79         // Transform map into JSON
80         sassMap = JSON.parse(sassObj.map.toString());
81         // Grab the stdout and transform it into stdin
82         sassMapFile = sassMap.file.replace(/^stdout$/, 'stdin');
83         // Grab the base file name that's being worked on
84         sassFileSrc = file.relative;
85         // Grab the path portion of the file that's being worked on
86         sassFileSrcPath = path.dirname(sassFileSrc);
87         if (sassFileSrcPath) {
88           //Prepend the path to all files in the sources array except the file that's being worked on
89           sourceFileIndex = sassMap.sources.indexOf(sassMapFile);
90           sassMap.sources = sassMap.sources.map(function(source, index) {
91             return (index === sourceFileIndex) ? source : path.join(sassFileSrcPath, source);
92           });
93         }
94
95         // Remove 'stdin' from souces and replace with filenames!
96         sassMap.sources = sassMap.sources.filter(function(src) {
97           if (src !== 'stdin') {
98             return src;
99           }
100         });
101
102         // Replace the map file with the original file name (but new extension)
103         sassMap.file = gutil.replaceExtension(sassFileSrc, '.css');
104         // Apply the map
105         applySourceMap(file, sassMap);
106       }
107
108       file.contents = sassObj.css;
109       file.path = gutil.replaceExtension(file.path, '.css');
110
111       cb(null, file);
112     };
113
114     //////////////////////////////
115     // Handles error message
116     //////////////////////////////
117     errorM = function errorM(error) {
118       var relativePath = '',
119           filePath = error.file === 'stdin' ? file.path : error.file,
120           message = '';
121
122       filePath = filePath ? filePath : file.path;
123       relativePath = path.relative(process.cwd(), filePath);
124
125       message += gutil.colors.underline(relativePath) + '\n';
126       message += error.formatted;
127
128       error.messageFormatted = message;
129       error.messageOriginal = error.message;
130       error.message = gutil.colors.stripColor(message);
131
132       error.relativePath = relativePath;
133
134       return cb(new gutil.PluginError(
135           PLUGIN_NAME, error
136         ));
137     };
138
139     if (sync !== true) {
140       //////////////////////////////
141       // Async Sass render
142       //////////////////////////////
143       callback = function(error, obj) {
144         if (error) {
145           return errorM(error);
146         }
147         filePush(obj);
148       };
149
150       gulpSass.compiler.render(opts, callback);
151     }
152     else {
153       //////////////////////////////
154       // Sync Sass render
155       //////////////////////////////
156       try {
157         result = gulpSass.compiler.renderSync(opts);
158
159         filePush(result);
160       }
161       catch (error) {
162         return errorM(error);
163       }
164     }
165   });
166 };
167
168 //////////////////////////////
169 // Sync Sass render
170 //////////////////////////////
171 gulpSass.sync = function sync(options) {
172   return gulpSass(options, true);
173 };
174
175 //////////////////////////////
176 // Log errors nicely
177 //////////////////////////////
178 gulpSass.logError = function logError(error) {
179   var message = new gutil.PluginError('sass', error.messageFormatted).toString();
180   process.stderr.write(message + '\n');
181   this.emit('end');
182 };
183
184 //////////////////////////////
185 // Store compiler in a prop
186 //////////////////////////////
187 gulpSass.compiler = require('node-sass');
188
189 module.exports = gulpSass;