-
Notifications
You must be signed in to change notification settings - Fork 5
/
postcss.resize.js
64 lines (51 loc) · 2.22 KB
/
postcss.resize.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
const { URLSearchParams } = require('node:url');
const postcss = require('postcss');
const postcssUrl = require('postcss-url');
const IMAGE_PATTERN = /.(png|jpg|jpeg)(\?.*)?$/i;
const FORMAT_IGNORE = /^(webp|avif)$/i;
module.exports = (extension) => {
const plugin = postcssUrl({
url(asset, dir, options, decl) {
const { originUrl } = asset;
if (!IMAGE_PATTERN.test(originUrl)) return originUrl;
const [originRequest, originSearch = ''] = originUrl.split('?', 2);
const originParams = new URLSearchParams(originSearch);
const originFormat = originParams.get('format');
if (originFormat && FORMAT_IGNORE.test(originFormat)) return originUrl;
const originRule = decl.parent;
let ignoreRule = false;
const ignoreText = `postcss.resize.${extension}: ignore`;
originRule.walkComments((item) => {
if (item.text === ignoreText) {
ignoreRule = true;
}
});
if (ignoreRule) return originUrl;
originParams.set('resize', '');
originParams.set('format', extension);
const newUrl = [originRequest, originParams].join('?');
let newRule = originRule[`postcss.resize.${extension}`];
if (!newRule) {
newRule = originRule.cloneAfter();
originRule[`postcss.resize.${extension}`] = newRule;
newRule.selectors = newRule.selectors.map((item) => `html.${extension} ${item}`);
newRule.each((item) => {
if (item.prop !== decl.prop && item.value !== decl.value) {
item.remove();
}
});
newRule.raws.semicolon = true;
newRule.raws.before = '\n';
newRule.prepend(postcss.comment({ text: ignoreText }));
}
newRule.each((item) => {
if (item.value) {
item.value = item.value.replace(originUrl, newUrl);
}
});
return originUrl;
},
});
plugin.postcssPlugin = `postcss.resize.${extension}.js`;
return plugin;
};