-
-
Notifications
You must be signed in to change notification settings - Fork 608
/
Copy pathindex.js
118 lines (113 loc) · 3.17 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
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var csso = require("csso");
module.exports = function(content) {
this.cacheable && this.cacheable();
var isRequireUrl = !this || !this.options || !this.options.css ||
typeof this.options.css.requireUrl === "string";
var requireUrl = this && this.options && this.options.css &&
this.options.css.requireUrl ||
"file/auto!";
var result = [];
var tree = csso.parse(content, "stylesheet");
if(this && this.minimize)
tree = csso.compress(tree);
tree = csso.cleanInfo(tree);
var imports = extractImports(tree);
if(isRequireUrl)
annotateUrls(tree);
imports.forEach(function(imp) {
if(imp.media.length > 0) {
result.push(JSON.stringify("@media " + imp.media.join("") + "{"));
}
result.push("require(" + JSON.stringify(__filename + "!" + urlToRequire(imp.url)) + ")");
if(imp.media.length > 0) {
result.push(JSON.stringify("}"));
}
});
var css = JSON.stringify(csso.translate(tree));
if(isRequireUrl) {
var uriRegExp = /%CSSURL\[%(.*?)%\]CSSURL%/g;
css = css.replace(uriRegExp, function(str) {
match = /^%CSSURL\[%(.*?)%\]CSSURL%$/.exec(str);
var url = JSON.parse("\"" + match[1] + "\"");
return "\"+require(" + JSON.stringify(requireUrl + urlToRequire(url)) + ")+\"";
});
}
result.push(css);
return "module.exports =\n\t" + result.join(" +\n\t") + ";";
}
function urlToRequire(url) {
if(/^~/.test(url))
return url.substring(1);
else
return "./"+url;
}
function extractImports(tree) {
var results = [];
var removes = [];
for(var i = 1; i < tree.length; i++) {
var rule = tree[i];
if(rule[0] === "atrules" &&
rule[1][0] === "atkeyword" &&
rule[1][1][0] === "ident" &&
rule[1][1][1] === "import") {
var imp = {
url: null,
media: []
};
for(var j = 2; j < rule.length; j++) {
var item = rule[j];
if(item[0] === "string") {
imp.url = JSON.parse(item[1]);
} else if(item[0] === "uri") {
imp.url = item[1][0] === "string" ? JSON.parse(item[1][1]) : item[1][1];
} else if(item[0] === "ident" && item[1] !== "url") {
imp.media.push(csso.translate(item));
} else if(item[0] !== "s" || imp.media.length > 0) {
imp.media.push(csso.translate(item));
}
}
while(imp.media.length > 0 &&
/^\s*$/.test(imp.media[imp.media.length-1]))
imp.media.pop();
if(imp.url !== null) {
results.push(imp);
removes.push(i);
}
}
}
removes.reverse().forEach(function(i) {
tree.splice(i, 1);
});
return results;
}
function annotateUrls(tree) {
function iterateChildren() {
for(var i = 1; i < tree.length; i++) {
annotateUrls(tree[i]);
}
}
switch(tree[0]) {
case "stylesheet": return iterateChildren();
case "ruleset": return iterateChildren();
case "block": return iterateChildren();
case "declaration": return iterateChildren();
case "value": return iterateChildren();
case "uri":
for(var i = 1; i < tree.length; i++) {
var item = tree[i];
switch(item[0]) {
case "ident":
case "raw":
item[1] = "%CSSURL[%" + item[1] + "%]CSSURL%";
return;
case "string":
item[1] = "%CSSURL[%" + item[1].substring(1, item[1].length-1) + "%]CSSURL%";
return;
}
}
}
}