/
uncss-inline.js
113 lines (96 loc) · 3.28 KB
/
uncss-inline.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* grunt-uncss-inline
* https://github.com/sparanoid/grunt-uncss-inline
*
* Copyright (c) 2016 Tunghsiao Liu
* Licensed under the MIT license.
*/
/**
* grunt-uncss
* https://github.com/addyosmani/grunt-uncss
*
* Copyright (c) 2016 Addy Osmani
* Licensed under the MIT license.
*/
module.exports = function ( grunt ) {
'use strict';
var uncss = require( 'uncss' ),
chalk = require( 'chalk' ),
maxmin = require( 'maxmin' ),
async = require( 'async' ),
cheerio = require( 'cheerio' );
grunt.registerMultiTask( 'uncss_inline', 'Remove unused CSS', function () {
var done = this.async();
var options = this.options({
report: 'min',
// We need to ignore ALL stylesheets (.css in <link>) in order for this
// plugin to work properly. Since we're only focus on inlined stylesheets
// in <style> tags.
ignoreSheets: [/.*/]
});
function processFile ( file, done ) {
// Get stylesheets from inline <style>
var $ = cheerio.load(grunt.file.read(file.src), {
decodeEntities: false
});
var src = file.src.filter(function ( filepath ) {
// Warn on and remove invalid source files (if nonull was set).
if ( !grunt.file.exists( filepath ) ) {
grunt.log.warn( 'Source file ' + chalk.cyan( filepath ) + ' not found.' );
return false;
} else {
return true;
}
});
if ( src.length === 0 && file.src.length === 0 ) {
grunt.fail.warn( 'Destination (' + file.dest + ') not written because src files were empty.' );
}
var styles = [];
if ($('style').length) {
$('style').each(function () {
var style = $(this).html();
if (style) {
styles.push(style);
options.raw = styles.join(' ');
}
});
} else {
// This is tricky but it works, if no stylesheets found, just throw a
// blank string to UnCSS to avoid "no stylesheets" error.
options.raw = ' ';
}
try {
uncss( src, options, function ( error, output, report ) {
if ( error ) {
throw error;
}
// remove all `<style>` tags except the first one
$('style').slice(1).remove();
$('style').text(output);
var html = $.html();
grunt.file.write( file.dest, html );
grunt.log.writeln('File ' + chalk.cyan( file.dest ) + ' created: ' + maxmin( report.original, output, options.report === 'gzip' ) );
if (typeof(options.reportFile) !== 'undefined' && options.reportFile.length > 0) {
grunt.file.write(options.reportFile, JSON.stringify(report));
}
done();
});
} catch ( e ) {
var err = new Error( 'Uncss failed.' );
if ( e.msg ) {
err.message += ', ' + e.msg + '.';
}
err.origError = e;
grunt.log.warn( 'Uncssing source "' + src + '" failed.' );
grunt.fail.warn( err );
}
}
if (this.files.length === 1) {
processFile( this.files[0], done );
} else {
// Processing multiple files must be done sequentially
// until https://github.com/giakki/uncss/issues/136 is resolved.
async.eachSeries( this.files, processFile, done );
}
});
};