-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
50 lines (45 loc) · 1.52 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
const DEFAULT_OTIONS = {
modules: false,
noAvifClass: 'no-avif',
avifClass: 'avif',
rename: oldName => oldName.replace(/\.(jpe?g|png)/gi, '.avif')
}
module.exports = (opts = {}) => {
const {modules, noAvifClass, avifClass, rename} = {...DEFAULT_OTIONS, ...opts}
function addClass(selector, className) {
className = modules ? `:global(.${className})` : `.${className}`
return selector.includes('html')
? selector.replace(/html[^ ]*/, `$& body${className}`)
: `body${className} ` + selector
}
return {
postcssPlugin: 'avif-in-css',
Declaration(decl) {
if (/\.(jpe?g|png)(?!(\.avif|.*[&?]format=avif))/i.test(decl.value)) {
const rule = decl.parent
if (rule.selector.includes(`.${noAvifClass}`)) return
const avif = rule.cloneAfter()
avif.each(i => {
if (i.prop !== decl.prop && i.value !== decl.value) i.remove()
})
avif.selectors = avif.selectors.map(i => addClass(i, avifClass))
avif.each(i => {
if (
rename &&
Object.prototype.toString.call(rename) === '[object Function]'
) {
i.value = rename(i.value)
}
})
const noAvif = rule.cloneAfter()
noAvif.each(i => {
if (i.prop !== decl.prop && i.value !== decl.value) i.remove()
})
noAvif.selectors = noAvif.selectors.map(i => addClass(i, noAvifClass))
decl.remove()
if (rule.nodes.length === 0) rule.remove()
}
}
}
}
module.exports.postcss = true