diff --git a/README.md b/README.md index 07781b8..41ced78 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ var uglify = require('gulp-uglify'); gulp.task('copy-js', function() { gulp.src('./src/*.html') .pipe(ghtmlSrc()) - // From this point, it's as if you'd used gulp.src() listing each of your + // From this point, it's as if you'd used gulp.src() listing each of your // javascript files that are in your html as .pipe(uglify()) .pipe(gulp.dest('./build/')); @@ -55,7 +55,7 @@ It will skip any script or link tags with data-remove="true" or data-ignore="tru Type: `bool` Default: `false` - + By default the original HTML file (that probably came from gulp.src()) is swallowed by `gulp-html-src`, and it only emits the matching script or css files. However, if you want to keep the HTML in the stream, then set this option to true. One use of this could be to blindly copy the HTML and all references to a destination directory. @@ -68,7 +68,7 @@ The following options are not used for the "normal" cases, but could be useful i Type: `String` Default: For presets == `script`, `script:not([data-ignore=true], [data-remove=true])`, for presets == `css`, `link[type="text/css"][rel=stylesheet]:not([data-ignore=true], [data-remove=true])` - + This is the [cheerio](https://github.com/cheeriojs/cheerio) selector (basically a jQuery selector) for the elements to select. See `options.getFileName` for how this element is converted to a filename. @@ -86,5 +86,8 @@ function getFileName(node) { } ``` +### options.base + Type: `String` +If `options.base` is set, the base for the created file is set to match the given `base` rather than the html-file base. This helps when the js and css files are stored in different folders for development and production. diff --git a/index.js b/index.js index 183cfe2..c3ce4f1 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ var fs = require('fs'), path = require('path'), url = require('url'), - File = require('vinyl'), + File = require('vinyl'), cheerio = require('cheerio'), through = require('through2'), extend = require('extend'), @@ -11,7 +11,8 @@ module.exports = function(options) { var defaults = { presets: 'script', includeHtmlInOutput: false, - createReadStream : fs.createReadStream + createReadStream : fs.createReadStream, + base: null }; var presets = { @@ -28,9 +29,9 @@ module.exports = function(options) { var selectedPresets = (options && options.presets && presets[options.presets]) || presets[defaults.presets]; - + options = extend({}, defaults, selectedPresets, options); - + var makeAbsoluteFileName = function makeAbsoluteFileName(file, fileName) { //return file.base + fileName; // path.join(file.base, fileName); return path.join(path.dirname(file.path), fileName); @@ -84,9 +85,9 @@ module.exports = function(options) { var transform = function(file, enc, callback) { var stream = this; var bufferReadPromises = []; - var fileNames; - var files = []; - + var fileNames; + var files = []; + if (file.isNull()) { // No contents - do nothing stream.push(file); @@ -103,10 +104,18 @@ module.exports = function(options) { // Iterate over found file names. fileNames.forEach(function (fileName) { if (isRelative(fileName)) { - var absoluteFileName = makeAbsoluteFileName(file, fileName); + var absoluteFileName, fileBase; + if (options.base) { + absoluteFileName = path.join(file.cwd, options.base, fileName); + fileBase = options.base; + } + else { + absoluteFileName = makeAbsoluteFileName(file, fileName); + fileBase = file.base; + } stream.push(new File({ cwd: file.cwd, - base: file.base, + base: fileBase, path: absoluteFileName, contents: options.createReadStream(absoluteFileName) })); @@ -133,12 +142,20 @@ module.exports = function(options) { fileNames.forEach(function (fileName, index) { if (isRelative(fileName)) { try { - var absoluteFileName = makeAbsoluteFileName(file, fileName); + var absoluteFileName, fileBase; + if (options.base) { + absoluteFileName = path.join(file.cwd, options.base, fileName); + fileBase = options.base; + } + else { + absoluteFileName = makeAbsoluteFileName(file, fileName); + fileBase = file.base; + } var readPromise = streamToBuffer(options.createReadStream(absoluteFileName)) .then(function(contents) { files[index] = new File({ cwd: file.cwd, - base: file.base, + base: fileBase, path: absoluteFileName, contents: contents }); @@ -169,6 +186,6 @@ module.exports = function(options) { }); } }; - + return through.obj(transform); } diff --git a/test/test.js b/test/test.js index dc33ba4..d868d38 100644 --- a/test/test.js +++ b/test/test.js @@ -12,7 +12,7 @@ var path = require('path'), describe('gulp-html-src', function() { var createFakeReadStream = function(path) { var stream = new PassThrough(); - setTimeout(function() { + setTimeout(function() { stream.write('FAKEFILE:'); stream.write(path); stream.end(); @@ -47,11 +47,11 @@ describe('gulp-html-src', function() { var dataReceived = false; var stream = ghtmlsrc(); - stream.on('data', function(data) { - dataReceived = true; + stream.on('data', function(data) { + dataReceived = true; }); - stream.on('end', function() { + stream.on('end', function() { expect(dataReceived).to.equal(false); done(); }); @@ -67,10 +67,10 @@ describe('gulp-html-src', function() { }); describe('for Buffer files', function() { - + var runForInput = function(html, options, asserts) { var dataReceived = []; - + // Skip options if not provided if (typeof options === 'function') { asserts = options; @@ -80,7 +80,7 @@ describe('gulp-html-src', function() { options = extend({}, { createReadStream : createFakeReadStream }, options); var stream = ghtmlsrc(options); - stream.on('data', function(data) { + stream.on('data', function(data) { dataReceived.push(data); }); @@ -88,7 +88,7 @@ describe('gulp-html-src', function() { console.log('error received ', err); }) - stream.on('end', function() { + stream.on('end', function() { asserts(dataReceived); }); @@ -105,9 +105,9 @@ describe('gulp-html-src', function() { it('should emit a single entry for one script', function(done) { - runForInput('' + + runForInput('' + '' + - '' + + '' + '', function(dataReceived) { expect(dataReceived.length).to.equal(1); @@ -116,20 +116,20 @@ describe('gulp-html-src', function() { done(); } ); - + }); it('should emit an entry for each script', function(done) { runForInput( - '' + + '' + '' + '' + '' + - '' + + '' + '', - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(3); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/js/test1.js')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/js/test1.js')); @@ -144,13 +144,13 @@ describe('gulp-html-src', function() { it('should ignore data-ignore=true scripts', function(done) { runForInput( - '' + + '' + '' + '' + '' + - '' + + '' + '', - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(2); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/js/test1.js')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/js/test1.js')); @@ -163,13 +163,13 @@ describe('gulp-html-src', function() { it('should ignore data-remove=true scripts', function(done) { runForInput( - '' + + '' + '' + '' + '' + - '' + + '' + '', - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(2); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/js/test1.js')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/js/test1.js')); @@ -182,14 +182,14 @@ describe('gulp-html-src', function() { it('should include the html file in transformed stream when the option is set', function(done) { runForInput( - '' + + '' + '' + '' + '' + - '' + + '' + '', { includeHtmlInOutput : true }, - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(3); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/js/test1.js')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/js/test1.js')); @@ -199,7 +199,7 @@ describe('gulp-html-src', function() { done(); } ); - + }); it('should emit a single css for css presets', function(done) { @@ -207,21 +207,21 @@ describe('gulp-html-src', function() { '' + '' + '' + - '' + + '' + '' + '' + '' + - '' + + '' + '', { presets : 'css' }, - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(1); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/css/test1.css')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/css/test1.css')); done(); } ); - + }); it('should emit a multiple css for css presets', function(done) { @@ -230,14 +230,14 @@ describe('gulp-html-src', function() { '' + '' + '' + - '' + + '' + '' + '' + '' + - '' + + '' + '', { presets : 'css' }, - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(2); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/css/test1.css')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/css/test1.css')); @@ -246,7 +246,7 @@ describe('gulp-html-src', function() { done(); } ); - + }); @@ -257,14 +257,14 @@ describe('gulp-html-src', function() { '' + '' + '' + - '' + + '' + '' + '' + '' + - '' + + '' + '', { presets : 'css' }, - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(2); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/css/test1.css')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/css/test1.css')); @@ -273,7 +273,7 @@ describe('gulp-html-src', function() { done(); } ); - + }); @@ -285,14 +285,14 @@ describe('gulp-html-src', function() { '' + '' + '' + - '' + + '' + '' + '' + '' + - '' + + '' + '', { presets : 'css' }, - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(2); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/css/test1.css')); expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/test/html/css/test1.css')); @@ -301,7 +301,7 @@ describe('gulp-html-src', function() { done(); } ); - + }); @@ -313,7 +313,7 @@ describe('gulp-html-src', function() { throw new Error('path not found') } } ); - stream.on('data', function(data) { + stream.on('data', function(data) { dataReceived.push(data); }); @@ -321,7 +321,7 @@ describe('gulp-html-src', function() { errorsReceived.push(err); }) - stream.on('end', function() { + stream.on('end', function() { expect(errorsReceived.length).to.equal(1); expect(errorsReceived[0]).to.be.an.instanceOf(Error); expect(errorsReceived[0].message).to.equal('path not found'); @@ -337,25 +337,25 @@ describe('gulp-html-src', function() { stream.read(); stream.end(); - + }); it('should skip absolute http:// scripts', function(done) { runForInput( '' + - '' + + '' + '' + '' + '' + - '' + + '' + '', { presets : 'js' }, - function(dataReceived) { + function(dataReceived) { expect(dataReceived.length).to.equal(2); expect(dataReceived[0].path).to.equal(path.normalize('/test/html/js/test1.js')); expect(dataReceived[1].path).to.equal(path.normalize('/test/html/js/test2.js')); - + done(); }); @@ -383,13 +383,32 @@ describe('gulp-html-src', function() { }); + it('respect a given base option', function(done) { + runForInput('' + + '' + + '' + + '', + { + base: "baseFolder" + }, + function(dataReceived) { + expect(dataReceived.length).to.equal(1); + expect(dataReceived[0].path).to.equal(path.normalize('/baseFolder/js/test1.js')); + expect(dataReceived[0].contents.toString()).to.equal('FAKEFILE:' + path.normalize('/baseFolder/js/test1.js')); + done(); + } + ); + + + }); + }); - - + + describe('for streams', function() { var createHtmlStream = function(contents) { var stream = new PassThrough(); - setTimeout(function() { + setTimeout(function() { stream.write(contents); stream.end(); }, 0); @@ -409,15 +428,15 @@ describe('gulp-html-src', function() { options = extend({}, { createReadStream : createFakeReadStream }, options); var stream = ghtmlsrc(options); - stream.on('data', function(data) { + stream.on('data', function(data) { dataReceived.push(data); }); - stream.on('error', function(err) { + stream.on('error', function(err) { errorsReceived.push(err); }); - stream.on('end', function() { + stream.on('end', function() { asserts(errorsReceived, dataReceived); }); @@ -436,10 +455,14 @@ describe('gulp-html-src', function() { var deferred = q.defer(); var contents = []; stream.on('readable', function() { - contents.push(stream.read()); + var data = stream.read(); + if (data) + { + contents.push(data); + } }); - stream.on('error', function(err) { + stream.on('error', function(err) { deferred.reject(err); }); @@ -491,12 +514,12 @@ describe('gulp-html-src', function() { }) .then(done, done); - + }); }); }); - -}); \ No newline at end of file + +});