-
Notifications
You must be signed in to change notification settings - Fork 16
/
css.js
139 lines (125 loc) · 3.85 KB
/
css.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
var rebase = require("../rebase");
var CSSO = require("csso");
var URL = require("url2");
module.exports = transformCss;
function transformCss(file, config, callback) {
file.utf8 = rebaseCss(file.utf8, file, config);
if (callback) {
callback();
}
}
transformCss.rebase = rebaseCss;
function rebaseCss(css, file, config) {
// Handle empty CSS files
if (config.noCss || !css.trim()) {
return css;
}
var ast;
try {
ast = CSSO.parse(css);
} catch (exception) {
config.out.warn("CSS parse error: " + file.path);
config.out.warn(exception.message);
return css;
}
var worklist = [ast];
while (worklist.length) {
var node = worklist.pop(), quote;
if (node[0] === "uri") {
var value = node[1], uri;
if (value[0] === "raw") {
uri = value[1];
quote = "";
} else if (value[0] === "string") {
// remove quotes (first and last character)
quote = value[1].substring(0,1);
uri = value[1].substring(1, value[1].length - 1);
// turn quoted URIs into unquoted as special characters are
// escaped by rebase
node[1] = value = ["raw"];
} else {
config.out.warn("Unknown URI type:", value);
continue;
}
value[1] = quote+rebase(uri, file, config)+quote;
}
for (var i = node.length - 1; i >= 0; i--) {
if (Array.isArray(node[i])) {
worklist.push(node[i]);
}
}
}
try {
ast = CSSO.compress(ast);
} catch (error) {
config.out.warn("CSS compression error: " + file.path);
config.out.warn(error.message);
}
try {
ast = CSSO.cleanInfo(ast);
} catch (error) {
config.out.warn("CSS clean info error: " + file.path);
config.out.warn(error.message);
}
return CSSO.translate(ast);
}
transformCss.resolve = resolveCss;
function resolveCss(base, css, config) {
var worklist,
quote,
value,
node,
ast,
uri,
i;
try {
ast = CSSO.parse(css);
} catch (exception) {
config.out.warn("CSS parse error prevented embedded CSS to be resolved: " + base);
return css;
}
if (ast) {
worklist = [ast];
while (worklist.length) {
node = worklist.pop();
if (node[0] === "uri") {
value = node[1];
if (value[0] === "raw") {
uri = value[1];
quote = "";
} else if (value[0] === "string") {
// remove quotes (first and last character)
quote = value[1].substring(0, 1);
uri = value[1].substring(1, value[1].length - 1);
// turn quoted URIs into unquoted as special characters are
// escaped by rebase
node[1] = value = ["raw"];
} else {
config.out.warn("Unknown URI type:", value);
continue;
}
if (uri.indexOf(":") === -1) {
value[1] = quote + URL.resolve(base, uri) + quote;
}
}
for (i = node.length - 1; i >= 0; i--) {
if (Array.isArray(node[i])) {
worklist.push(node[i]);
}
}
}
}
try {
ast = CSSO.compress(ast);
} catch (error) {
config.out.warn("CSS compression error: ");
config.out.warn(error.message);
}
try {
ast = CSSO.cleanInfo(ast);
} catch (error) {
config.out.warn("CSS clean info error:");
config.out.warn(error.message);
}
return CSSO.translate(ast);
}