-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.js
139 lines (127 loc) · 5.07 KB
/
build.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
128
129
130
131
132
133
134
135
136
137
138
139
const fs = require('fs');
const path = require('path');
const CleanCSS = require('clean-css');
const UglifyJS = require("uglify-js");
const svgFolderPath = "./res/svg/optimized";
const cssAnimPath = "./src/pixelarticons_anim.css";
const isFile = fileName => {
return fs.lstatSync(fileName).isFile();
};
const svgFileList = fs.readdirSync(svgFolderPath)
.map(fileName => {
return path.join(svgFolderPath, fileName);
})
.filter(isFile);
const svgAnimFileList = fs.readdirSync("./res/svg/optimized/anim")
.map(fileName => {
return path.join("./res/svg/optimized/anim", fileName);
})
.filter(isFile);
function fileContentList(fileList) {
const list = [];
for (let i = 0; i < fileList.length; i++) {
list.push({
name: path.basename(fileList[i], path.extname(fileList[i])),
content: fs.readFileSync(path.resolve(fileList[i]), 'utf8')
});
}
return list;
}
const svgList = fileContentList(svgFileList);
const svgAnimList = fileContentList(svgAnimFileList);
// Method 1: store all SVG contents in a map
function jsM1Build(svgList, svgAnimList) {
let output = `const pxicoIconMap = new Map([`;
for (let i = 0; i < svgList.length; i++) {
output += `["${svgList[i].name}", \`${svgList[i].content}\`],`;
}
for (let i = 0; i < svgAnimList.length; i++) {
output += `["${svgAnimList[i].name}_anim", \`${svgAnimList[i].content}\`],`;
}
output += "]);";
const minifyInput = output + fs.readFileSync("./src/pixelarticons.js", 'utf8');
return UglifyJS.minify(minifyInput).code;
}
try {
fs.writeFileSync('./dist/pixelarticons.js', jsM1Build(svgList, svgAnimList));
console.log("JS method 1 written");
} catch (err) {
console.error("!!! Error at JS method 1 write !!! " + err);
}
// Method 2: generate <img> with src attribute to an external SVG.
function jsM2Build() {
return UglifyJS.minify(fs.readFileSync("./src/pixelarticons_ext.js", 'utf8')).code;
}
try {
fs.writeFileSync('./dist/pixelarticons_ext.js', jsM2Build());
console.log("JS method 2 written");
} catch (err) {
console.error("!!! Error at JS method 2 write !!! " + err);
}
// Method 3: CSS file with background image URL's containing the SVG's encoded data URI
function cssM3Build(svgList, svgAnimList) {
let output = fs.readFileSync("./src/pixelarticons.css", 'utf8');
for (let i = 0; i < svgList.length; i++) {
output += `i.pxico-${svgList[i].name} { background-image: url("${svgToDataURI(svgList[i].content)}"); }`;
}
for (let i = 0; i < svgAnimList.length; i++) {
output += `i.pxico-${svgAnimList[i].name}_anim { background-image: url("${svgToDataURI(svgAnimList[i].content)}"); }`;
}
const minifiedOutput = new CleanCSS().minify(output).styles;
return minifiedOutput;
}
try {
fs.writeFileSync('./dist/pixelarticons.css', cssM3Build(svgList, svgAnimList));
console.log("CSS method 3 written");
} catch (err) {
console.error("!!! Error at CSS method 3 write !!! " + err);
}
function cssAnimBuild(cssAnimPath) {
const minifiedOutput = new CleanCSS().minify(fs.readFileSync(path.resolve(cssAnimPath), 'utf8')).styles;
return minifiedOutput;
}
try {
fs.writeFileSync('./dist/pixelarticons_anim.css', cssAnimBuild(cssAnimPath));
console.log("CSS animations written");
} catch (err) {
console.error("!!! Error at CSS animations write !!! " + err);
}
function svgToDataURI(svg) {
/*
Function by heyallan under the mit license: https://github.com/heyallan/svg-to-data-uri/blob/master/LICENSE
Repository: https://github.com/heyallan/svg-to-data-uri
*/
svg = svg.trim();
// remove xml, doctype, generator...
svg = svg.slice(svg.indexOf('<svg'));
// soft validate
if (!svg.startsWith('<svg') || !svg.endsWith('svg>')) return;
// add namespace if necessary
if (!svg.includes('http://www.w3.org/2000/svg')) svg = svg.replace(/<svg/g, `<svg xmlns='http://www.w3.org/2000/svg'`);
// remove comments
svg = svg.replace(/<!--.{1,}-->/g, '');
// remove unnecessary attributes
svg = svg.replace(/version=[\"\'](.{0,}?)[\"\'](?=[\s>])/g, '');
// svg = svg.replace(/id=[\"\'](.{0,}?)[\"\'](?=[\s>])/g, '');
// svg = svg.replace(/class=[\"\'](.{0,}?)[\"\'](?=[\s>])/g, '');
// replace nested quotes
svg = svg.replace(/"'(.{1,})'"/g, '\'$1\'');
// replace double quotes
svg = svg.replace(/"/g, '\'');
// remove empty spaces between tags
svg = svg.replace(/>\s{1,}</g, '><');
// remove duplicate spaces
svg = svg.replace(/\s{2,}/g, ' ');
// trim again
svg = svg.trim();
// soft validate again
if (!(svg.startsWith('<svg')) || !(svg.endsWith('svg>'))) return;
// replace ampersand
svg = svg.replace(/&/g, '&');
// encode only unsafe symbols
svg = svg.replace(/[%#<>?\[\\\]^`{|}]/g, encodeURIComponent);
// build data uri
svg = `data:image/svg+xml,${svg}`;
// ok, ship it!
return svg;
}