From 95842dfa09b662b4372ef15dbd353330670616e7 Mon Sep 17 00:00:00 2001 From: Michael Moussa Date: Wed, 11 Mar 2015 10:56:23 -0400 Subject: [PATCH] Added support for an automatic cache buster suffix on the bg image --- bin/cli.js | 5 +++++ lib/css-sprite.js | 10 ++++++++-- test/css-sprite.js | 24 ++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index fcfc7af..c68f3aa 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -69,6 +69,11 @@ var opts = require('nomnom') default: '#FFFFFF', help: 'background color of the sprite in hex' }) + .option('cachebuster', { + choices: ['random'], + default: false, + help: 'appends a "cache buster" to the background image in the form "?<...>" (random)' + }) .option('margin', { default: 4, help: 'margin in px between tiles' diff --git a/lib/css-sprite.js b/lib/css-sprite.js index 5930e46..51eb635 100644 --- a/lib/css-sprite.js +++ b/lib/css-sprite.js @@ -1,6 +1,7 @@ 'use strict'; var async = require('async'); +var crypto = require('crypto'); var through2 = require('through2'); var lodash = require('lodash'); var path = require('path'); @@ -107,11 +108,16 @@ module.exports = function (opt) { }); }); + var cachebuster = ''; + if (opt.cachebuster === 'random') { + cachebuster = '?' + crypto.randomBytes(20).toString('hex'); + } + if (retinaSprite) { sprites.unshift({ name: retinaSprite.relative, type: 'retina', - image: (!opt.base64) ? url.resolve(opt.cssPath.replace(/\\/g, '/'), retinaSprite.relative) : 'data:' + imageinfo(retinaSprite.buffer).mimeType + ';base64,' + retinaSprite.buffer.toString('base64'), + image: (!opt.base64) ? url.resolve(opt.cssPath.replace(/\\/g, '/'), retinaSprite.relative) + cachebuster : 'data:' + imageinfo(retinaSprite.buffer).mimeType + ';base64,' + retinaSprite.buffer.toString('base64'), total_width: sprite.canvas.width(), total_height: sprite.canvas.height() }); @@ -127,7 +133,7 @@ module.exports = function (opt) { sprites.unshift({ name: sprite.relative, type: 'sprite', - image: (!opt.base64) ? url.resolve(opt.cssPath.replace(/\\/g, '/'), sprite.relative) : 'data:' + imageinfo(sprite.buffer).mimeType + ';base64,' + sprite.buffer.toString('base64'), + image: (!opt.base64) ? url.resolve(opt.cssPath.replace(/\\/g, '/'), sprite.relative) + cachebuster : 'data:' + imageinfo(sprite.buffer).mimeType + ';base64,' + sprite.buffer.toString('base64'), total_width: sprite.canvas.width, total_height: sprite.canvas.height }); diff --git a/test/css-sprite.js b/test/css-sprite.js index 8bf507e..6af5d39 100644 --- a/test/css-sprite.js +++ b/test/css-sprite.js @@ -237,6 +237,30 @@ describe('css-sprite (lib/css-sprite.js)', function () { done(); }); }); + it('should include a random cache buster hash on the background-image, if desired', function (done) { + var css; + vfs.src('./test/fixtures/**') + .pipe(sprite({ + out: './dist/img', + name: 'sprites', + style: './dist/css/sprites.css', + cachebuster: 'random' + })) + .pipe(through2.obj(function (file, enc, cb) { + if (file.relative.indexOf('css') > -1) { + css = file; + } + cb(); + })) + .on('data', noop) + .on('end', function () { + css.should.be.ok; + css.path.should.equal('./dist/css/sprites.css'); + css.relative.should.equal('sprites.css'); + css.contents.toString('utf-8').should.match(/background-image: url\('..\/sprites.png\?[0-9a-f]{40}'\)/); + done(); + }); + }); it('should return a object stream with a sprite and a scss file', function (done) { var png, css; vfs.src('./test/fixtures/**')