UNPKG

gulp-avif-css-fix

Version:

Gulp plugin to use webp & avif in CSS

123 lines (102 loc) 3.08 kB
const through = require('through2'); const css = require('css'); class AvifCSS { constructor() { this.avaibleExtensions = ['png', 'PNG', 'jpg', 'jpeg', 'JPG', 'JPEG']; } init = extensions => { return through.obj((buffer, _, callback) => { if (buffer.isNull()) { return callback(null, buffer); } else if (buffer.isStream()) { return callback(null, buffer); } if (extensions) { this.avaibleExtensions = extensions; } this.buffer = buffer; this.fileData = buffer.contents.toString(); this.transform(); callback(null, this.buffer); }); }; transform(rules = this.parseCSS()) { rules.forEach(expression => { if (expression.type === 'media') { return this.transform(expression.rules); } else if (expression.type === 'rule') { expression.declarations.forEach(rule => { if (!this.isBackground(rule)) return; const imageExtension = this.getExtension(rule); if (!imageExtension) return; this.createExpressions({ rule, selectors: expression.selectors, position: expression.type === 'media' ? rule.position : expression.position, imageExtension, }); }); } }); this.buffer.contents = new Buffer.from(this.fileData); } parseCSS() { return css.parse(this.fileData).stylesheet.rules; } isBackground({ property, value }) { if ( property === 'background' || (property === 'background-image' && value.indexOf('.webp') < 0 && value.indexOf('.avif') < 0) ) { return true; } } getExtension({ value }) { return this.avaibleExtensions.find(extension => { if (value.indexOf(extension) > 0) { return extension; } }); } createExpressions({ rule, selectors, position, imageExtension }) { const splitedData = this.fileData.split(/\n/); const rowIndex = position.end.line - 1; const columnIndex = position.end.column - 1; ['avif', 'webp'].forEach(modernExtension => { splitedData.splice( rowIndex, 1, this.changeString( splitedData[rowIndex], columnIndex, selectors.join('') !== 'body' ? `\r\n.${modernExtension} ${selectors.join('')} {\n\t${ rule.property }: ${rule.value.replace( imageExtension, modernExtension )};\n\t}\r\n` : `\r\n${selectors.join('')}.${modernExtension} {\n\t${ rule.property }: ${rule.value.replace( imageExtension, modernExtension )};\n\t}\r\n` ) ); }); this.fileData = splitedData.join('\n'); } changeString(string, changeIndex, changeText) { return ( string.substring(0, changeIndex) + changeText + string.substring(changeIndex) ); } } const avifcss = new AvifCSS(); module.exports = avifcss.init;