-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
127 lines (110 loc) · 3.3 KB
/
index.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env node
var path = require('path');
var serveFolder = require('serve-folder');
var Nightmare = require('nightmare');
var getPort = require('get-port');
var cheerio = require('cheerio');
var fs = require('fs');
var Q = require('q');
var Promise = Q.Promise;
var SVGO = require('svgo');
var svgo = new SVGO({
full: true,
plugins: [{convertPathData: true}]
})
var minifySVG = function ($input, callback) {
var $svgs = $input('svg[data-prerender-minify]');
var count = $svgs.length;
var completed = 0;
if (count === 0) {
callback(null, $input);
}
$svgs.each(function(i) {
var svg = $input(this);
svgo.optimize($input.html(svg), function(result) {
completed++;
$input(svg).replaceWith(result.data);
if (completed === count) {
callback(null, $input);
}
});
});
};
var cleanHTML = function (originalHTML, outputHTML) {
var $original = cheerio.load(originalHTML);
var $output = cheerio.load(outputHTML);
var originalOptIns = $original('[data-prerender-only]');
if (originalOptIns.length) {
var outputOptIns = $output('[data-prerender-only]');
// If we see at least one 'opt-in' flag, only render the opt in
originalOptIns.each(function (i) {
$original(this).html(outputOptIns.eq(i).html());
return;
});
return $original;
}
var originalIgnores = $original('[data-prerender-ignore]');
$output('[data-prerender-ignore]').each(function (i) {
$output(this).html(originalIgnores.eq(i).html());
return;
});
return $output;
};
module.exports = function (options, callback) {
if (arguments.length < 2 || !options.inputFile) {
return callback(new Error('Must provide options dictionary with `inputFile` and a callback function'));
}
var inputHtmlPath = path.resolve(options.inputFile);
var originalHTML = fs.readFileSync(inputHtmlPath).toString();
if (options.preprocessHTML) {
fs.writeFileSync(inputHtmlPath, options.preprocessHTML(originalHTML));
}
var rootPath;
var basename;
if (options.basePath) {
rootPath = path.resolve(options.basePath);
basename = path.relative(rootPath, inputHtmlPath);
} else {
rootPath = path.dirname(inputHtmlPath);
basename = path.basename(inputHtmlPath);
}
var output;
var runPrerender = function (port) {
var server = serveFolder(rootPath, port);
var nightmare = Nightmare();
Promise.resolve(nightmare
.viewport(1920, 1080)
// .on('console', function (type, errorMessage, errorStack) {
// console.log(errorMessage);
// })
.goto('http://localhost:' + port + '/' + basename)
.wait(5000)
.evaluate(function () {
return document.documentElement.outerHTML;
})
).then(function (htmlOut) {
if (options.postprocessHTML) {
htmlOut = options.postprocessHTML(htmlOut);
}
return cleanHTML(originalHTML, htmlOut);
}).then(function ($html) {
return Q.nfcall(minifySVG, $html);
}).then(function ($output) {
output = $output.html();
server.close();
return nightmare.end();
}).then(function () {
callback(null, output);
}).catch(function (err) {
callback(err);
});
};
if (!options.port) {
getPort()
.then(function (port) {
runPrerender(port);
});
} else {
runPrerender(options.port);
}
};