UNPKG

gulp-assetpaths

Version:

A Gulp plugin to change asset paths from one environment to another.

224 lines (204 loc) 5.95 kB
var PluginError = require('plugin-error'); var through = require('through2'); module.exports = function(opts) { var rootRegEx; if (!opts) { throw new PluginError('gulp-assetpaths', 'No parameters supplied'); } if (!opts.filetypes || !opts.filetypes instanceof Array) { throw new PluginError( 'gulp-assetpaths', 'Missing parameter : filetypes' ); } if (typeof opts.newDomain !== 'string' && !opts.newDomain) { throw new PluginError( 'gulp-assetpaths', 'Missing parameter : newDomain' ); } if (!opts.oldDomain) { throw new PluginError( 'gulp-assetpaths', 'Missing parameter : oldDomain' ); } if (typeof opts.docRoot !== 'string' && !opts.docRoot) { throw new PluginError('gulp-assetpaths', 'Missing parameter : docRoot'); } var filetypes = new RegExp('.' + opts.filetypes.join('|.')); var rootRegEx = setReplacementDomain(opts.oldDomain); var attrsAndProps = [ { exp: /(<\s*)(.*?)\bhref\s*=\s*((["{0,1}|'{0,1}]).*?\4)(.*?)>/gi, captureGroup: 3, templateCheck: /((\bdownload)(?=(.*?)\bhref\s*=))|((\bhref\s*=)(?=(.*?)\bdownload))/ }, { exp: /((\bbackground|\bbackground-image)\s*:\s*?.*){0,1}\burl\s*((\(\s*[^\w]{0,1}(["{0,1}'{0,1}]{0,1})).*?\5\))/gi, captureGroup: 3, templateCheck: /((\bbackground|\bbackground-image)\s*:\s*?.*)\burl\s*\(.*?\)/ }, { exp: /((<\s*){0,1}\bscript)(.*?)\bsrc\s*=\s*((["{0,1}|'{0,1}]).*?\5)/gi, captureGroup: 4, templateCheck: /(<\s*){0,1}(\bscript)(.*?)\bsrc\s*=\s*/ }, { exp: /((<\s*){0,1}\bimg)(.*?)\bsrc\s*=\s*((["{0,1}|'{0,1}]).*?\5)/gi, captureGroup: 4, templateCheck: /(<\s*){0,1}(\bimg)(.*?)\bsrc\s*=\s*/ }, { exp: /(:\s*("(.*?)"))/gi, captureGroup: 2, templateCheck: false } ]; //create custom attributes expressions if (opts.customAttributes) { var customAttrs = opts.customAttributes.map(function(attr) { return { exp: new RegExp( '\\b' + attr + '\\s*=\\s*((["{0,1}|\'{0,1}]).*\\2)', 'gi' ), captureGroup: 1, templateCheck: /.*/ }; }); attrsAndProps = attrsAndProps.concat(customAttrs); } function setReplacementDomain(string) { if (isRelative(opts.oldDomain)) { return new RegExp( '(((\\bhttp|\\bhttps):){0,1}\\/\\/' + string + ')' ); } else { return new RegExp(string); } } function isRelative(string, insertIndex) { return string.indexOf('/') === -1 || string.indexOf('/') > insertIndex; } function getInsertIndex(string) { if (string.search(/^.{0,1}\s*("|')/) !== -1) { //check to see if template not using interpolated strings var nonInter = /["|']\s*[+|.][^.]/.exec(string); if (nonInter) { return string.search(/"|'/) === nonInter.index ? nonInter.index : nonInter.index - 1; } return string.search(/"|'/) + 1; } return 1; } function insertAtIndex(string, fragment, index) { return [string.slice(0, index), fragment, string.slice(index)].join(''); } function ignoreUrl(match) { var regEx = /((\bhttp|\bhttps):){0,1}\/\//; if (regEx.test(match)) { if (rootRegEx !== null && !rootRegEx.test(match)) { return true; } } return false; } function replacementCheck(cGroup, match, regEx) { if (!opts.templates) { return filetypes.test(cGroup); } if (regEx.templateCheck) { return filetypes.test(cGroup) || regEx.templateCheck.test(match); } else { return filetypes.test(cGroup); } } function processLine(line, regEx, file) { line = line.replace(regEx.exp, function(match) { var cGroup = arguments[regEx.captureGroup]; if (replacementCheck(cGroup, match, regEx)) { if (!ignoreUrl(cGroup)) { return match.replace(cGroup, function(match) { match = match.replace(rootRegEx, '').trim(); return insertPath(match, file); }); } } return match; }); //pass back line if noop return line; } function countRelativeDirs(path) { var relDirs = path.filter(function(dir) { return dir.indexOf('..') !== -1 ? true : false; }); return relDirs.length; } function anchorToRoot(string, file) { var index = getInsertIndex(string); if (isRelative(string, index)) { //if the path isn't being dynamically generated(i.e. server or in template) if (!/^\s*[\(]{0,1}\s*["|']{0,1}\s*[<|{|.|+][^.]/.test(string)) { if (opts.docRoot) { var currentPath = string.split('/'); var relDirs = countRelativeDirs(currentPath); string = string.replace(/\.\.\//g, ''); relDirs = relDirs > 0 ? relDirs : relDirs + 1; var fullPath = file.path .split('/') .reverse() .slice(relDirs); if (fullPath.indexOf(opts.docRoot) !== -1) { while (fullPath[0] !== opts.docRoot) { string = insertAtIndex( string, fullPath[0] + '/', index ); fullPath = fullPath.slice(1); } } } } } return string; } function insertPath(string, file) { var string = anchorToRoot(string, file); var index = getInsertIndex(string); if (isRelative(string, index)) { string = insertAtIndex(string, '/', index); } return insertAtIndex(string, opts.newDomain, index); } function assetpaths(file, enc, callback) { // Do nothing if no contents if (file.isNull()) { this.push(file); return callback(); } if (file.isStream()) { return this.emit( 'error', new PluginError('gulp-assetpaths', 'Streaming not supported') ); } if (file.isBuffer()) { var outfileContents = ''; var contents = file.contents.toString('utf8'); var lineEnding = contents.search(/[\r\n]/) !== -1 ? '\r\n' : '\n'; var lines = contents.split(lineEnding); lines.forEach(function(line) { attrsAndProps.forEach(function(regEx) { line = processLine(line, regEx, file); }, this); outfileContents += line; }, this); var outfile = file.clone(); outfile.contents = new Buffer(outfileContents); } this.push(outfile); return callback(); } return through.obj(assetpaths); };