1 | module.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 |
|
13 |
|
14 |
|
15 |
|
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 |
|
121 | if (addNewLine) {
|
122 | result += '\n';
|
123 | }
|
124 | grunt.verbose.ok();
|
125 |
|
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 | };
|