UNPKG

5.99 kBJavaScriptView Raw
1module.exports = function(grunt) {
2 "use strict";
3
4 var path = require('path'),
5 jsBeautifier = require('js-beautify'),
6 lodash = require('lodash'),
7 stringUtils = require('underscore.string'),
8 jsbeautifier = jsBeautifier.js,
9 cssbeautifier = jsBeautifier.css,
10 htmlbeautifier = jsBeautifier.html;
11
12 // Please see the grunt documentation for more information regarding task and
13 // helper creation: https://github.com/gruntjs/grunt/blob/master/docs/toc.md
14 // ==========================================================================
15 // TASKS
16 // ==========================================================================
17 grunt.task.registerMultiTask('jsbeautifier', 'jsbeautifier.org for grunt', function() {
18
19 var params = this.options({
20 mode: "VERIFY_AND_WRITE",
21 js: {},
22 css: {},
23 html: {}
24 });
25
26 var fileCount = 0;
27 var changedFileCount = 0;
28
29 function verifyActionHandler(src) {
30 grunt.fail.warn(src.cyan + ' was not beautified');
31 }
32
33 function verifyAndWriteActionHandler(src, result) {
34 grunt.file.write(src, result);
35 changedFileCount++;
36 }
37
38 function convertCamelCaseToUnderScore(config) {
39 var underscoreKey;
40 lodash.forEach([config.js, config.css, config.html], function(conf) {
41 lodash.forEach(conf, function(value, key) {
42 underscoreKey = stringUtils.underscored(key);
43 if ("fileTypes" !== key && key !== underscoreKey) {
44 conf[underscoreKey] = value;
45 delete conf[key];
46 }
47 });
48 });
49 }
50
51 if (this.filesSrc && this.filesSrc.length > 0) {
52 grunt.verbose.writeln('Beautifing using filesSrc with ' + this.filesSrc.length.toString().cyan + ' files...');
53
54 grunt.verbose.writeln('Using mode="' + params.mode + '"...');
55 var actionHandler = "VERIFY_ONLY" === params.mode ? verifyActionHandler : verifyAndWriteActionHandler;
56
57 var config;
58 if (params.config) {
59 var baseConfig = grunt.file.readJSON(path.resolve(params.config));
60 config = {
61 js: {},
62 css: {},
63 html: {}
64 };
65 lodash.extend(config.js, baseConfig);
66 lodash.extend(config.css, baseConfig);
67 lodash.extend(config.html, baseConfig);
68 lodash.extend(config.js, baseConfig.js);
69 lodash.extend(config.css, baseConfig.css);
70 lodash.extend(config.html, baseConfig.html);
71 lodash.extend(config.js, params.js);
72 lodash.extend(config.css, params.css);
73 lodash.extend(config.html, params.html);
74 } else {
75 config = params;
76 }
77 config.js.fileTypes = lodash.union(config.js.fileTypes, ['.js', '.json']);
78 config.css.fileTypes = lodash.union(config.css.fileTypes, ['.css']);
79 config.html.fileTypes = lodash.union(config.html.fileTypes, ['.html']);
80
81 grunt.verbose.writeln('Beautify config before converting camelcase to underscore: ' + JSON.stringify(config));
82
83 convertCamelCaseToUnderScore(config);
84
85 grunt.verbose.writeln('Using beautify config: ' + JSON.stringify(config));
86
87 var done = this.async();
88 var q = grunt.util.async.queue(function(src, callback) {
89 if (grunt.file.isDir(src)) {
90 callback();
91 return;
92 }
93
94 beautify(src, config, actionHandler);
95 fileCount++;
96 callback();
97 }, 10);
98 q.drain = function() {
99 grunt.log.write('Beautified ' + fileCount.toString().cyan + ' files, changed ' + changedFileCount.toString().cyan + ' files...');
100 grunt.log.ok();
101 done();
102 };
103 q.push(this.filesSrc);
104 }
105 });
106
107 function beautify(file, config, actionHandler) {
108 var setup = getBeautifierSetup(file, config);
109 if (!setup) {
110 return;
111 }
112
113 var beautifier = setup[0],
114 beautifyConfig = setup[1],
115 addNewLine = setup[2];
116
117 var original = grunt.file.read(file);
118 grunt.verbose.write('Beautifing ' + file.cyan + '...');
119 var result = beautifier(original, beautifyConfig);
120 // jsbeautifier would skip the line terminator for js files
121 if (addNewLine) {
122 result += '\n';
123 }
124 grunt.verbose.ok();
125 /*jshint eqeqeq: false */
126 if (original != result) {
127 actionHandler(file, result);
128 }
129 }
130
131 function getFileType(file, config) {
132 var fileType = null,
133 fileMapping = {
134 'js': config.js.fileTypes,
135 'css': config.css.fileTypes,
136 'html': config.html.fileTypes
137 };
138 lodash.forEach(fileMapping, function(extensions, type) {
139 fileType = type;
140 return -1 === lodash.findIndex(extensions, function(ext) {
141 return stringUtils.endsWith(file, ext);
142 });
143 });
144 return fileType;
145 }
146
147 function getBeautifierSetup(file, config) {
148 var fileType = getFileType(file, config);
149 switch (fileType) {
150 case 'js':
151 return [jsbeautifier, config.js, true];
152 case 'css':
153 return [cssbeautifier, config.css];
154 case 'html':
155 return [htmlbeautifier, config.html];
156 default:
157 grunt.fail.warn('Cannot beautify ' + file.cyan + ' (only js, css and html files can be beautified)');
158 return null;
159 }
160 }
161};