UNPKG

gulp-lazyimagecss

Version:

Be lazy, add images' CSS automatically, like width & height and more.

176 lines (136 loc) 6.21 kB
var fs = require('fs'); var path = require('path'); var File = require('vinyl'); var async = require('async'); var _ = require('lodash'); var through = require('through2'); var fastImageSize = require('./lib/fastimagesize'); var css = require('css'); function lazyImageCSS(options) { options = _.extend({ width: true, height: true, backgroundSize: true, imagePath: [], SVGGracefulDegradation: false }, options); return through.obj(function (file, enc, cb) { var cssContent = file.contents.toString(); var imagePath = options.imagePath; if (imagePath.length) { imagePath = '(' + options.imagePath.join('|') + '/)'; imagePath = imagePath.replace(/\./g, '\\.'); } else { imagePath = ''; } var imageRegex = new RegExp('url\\(["\']?(' + imagePath + '[^)]*?)["\']?\\)'); var obj = css.parse(cssContent); function setProperty(property, value) { return { "type": "declaration", "property": property, "value": value }; } function parseRules(rules) { for (var i = 0; i < rules.length; i++) { var rule = rules[i]; if (rule.type === 'keyframes') { parseRules(rule.keyframes); } if (rule.type === 'media') { parseRules(rule.rules); } if (rule.type === 'rule' || rule.type === 'keyframe') { var declarations = rule.declarations; var code = {}; declarations.forEach(function (declaration) { code[declaration.property] = declaration.value; }); var property; var hasImage = false; if (code['background-image']) { property = 'background-image'; hasImage = true; } else if (code['background']) { property = 'background'; hasImage = true; } if (!hasImage) { continue; } var value = code[property]; var matchValue = imageRegex.exec(value); if (!matchValue || matchValue[1].indexOf('data:') === 0) { continue; } var relativePath = matchValue[1]; var absolutePath = path.join(path.dirname(file.path), relativePath); if (value.indexOf('@2x') > -1) { options.retina = true; } else { options.retina = false; } var info = fastImageSize(absolutePath); if (info.type === 'unknown') { console.log('' + 'unknown type: ' + absolutePath); continue; } var width, height, newDeclaration; if (options.retina) { width = info.width / 2 + 'px'; height = info.height / 2 + 'px'; } else { width = info.width + 'px'; height = info.height + 'px'; } if (options.width && !code['width']) { newDeclaration = setProperty('width', width); declarations.push(newDeclaration); } if (options.height && !code['height']) { newDeclaration = setProperty('height', height); declarations.push(newDeclaration); } if(info.type == 'svg' && !code['background-size'] && !code['-webkit-background-size']){ newDeclaration = setProperty('background-size', '100% 100%'); declarations.push(newDeclaration); //降级 if(code['background-image'] && options.SVGGracefulDegradation){ declarations.forEach(function (declaration,i) { if(declaration.property == 'background-image'){ declarations[i].value = declarations[i].value.replace('.svg','.png'); } }); newDeclaration = setProperty('background-image', code['background-image']+ ',none'); declarations.push(newDeclaration); }else if(code['background'] && options.SVGGracefulDegradation){ declarations.forEach(function (declaration,i) { if(declaration.property == 'background'){ declarations[i].value = declarations[i].value.replace('.svg','.png'); } }); newDeclaration = setProperty('background', code['background'].replace(')','),none')); declarations.push(newDeclaration); } }else if(options.backgroundSize && (options.retina) && !code['background-size'] && !code['-webkit-background-size']) { newDeclaration = newDeclaration = setProperty('background-size', width + ' ' + height); declarations.push(newDeclaration); } } } } if (obj.stylesheet.rules.length > 0) { parseRules(obj.stylesheet.rules); cssContent = css.stringify(obj); } this.push(new File({ base: file.base, path: file.path, contents: new Buffer(cssContent) })); cb(); }); } // Exporting the plugin main function module.exports = lazyImageCSS;