diff --git a/index.js b/index.js index 7d3e96c..045a84d 100644 --- a/index.js +++ b/index.js @@ -17,6 +17,45 @@ function relative(a, b) { return relativePath.charAt(0) !== '.' ? './' + relativePath : relativePath; } +/* + * Checks if there is already a prepend in the current match. + */ +function alreadyHasPrepend(string, prepend, offset, submatch) { + var startIndex = offset + (submatch || "").length - prepend.length; + + // Can be a problem if startIndex is -1 and there is no + // prepend in string. + if (startIndex < 0) { + return false; + } + + return string.indexOf(prepend, startIndex) === startIndex; +} + +/** + * Creates a function to use as second argument in String.prototype.replace. + * The function avoids prepending twice. If the prepend needs to be applied, + * it removes leading relative path from the replacement. + * + * @param {String} replacement the string that will replace the match + * @param {String} prepend an string to prepend the replacement with. + */ +function replacer(replacement, prepend) { + var removeLeadingRelativeOrSlashRegex = new RegExp('^(\\.*/)*(.*)$'); + return function(match, submatch) { + var offset = arguments[arguments.length - 2]; + var string = arguments[arguments.length - 1]; + + if (alreadyHasPrepend(string, prepend, offset, submatch)) { + return submatch + replacement; + } + + // submatch would have been removed by removeLeadingRelativeOrSlashRegex, + // so no need to concat. + return prepend + removeLeadingRelativeOrSlashRegex.exec(replacement)[2]; + } +} + function AssetRewrite(inputNode, options) { if (!(this instanceof AssetRewrite)) { return new AssetRewrite(inputNode, options); @@ -121,11 +160,13 @@ AssetRewrite.prototype.rewriteAssetPath = function (string, assetPath, replaceme continue; } - replaceString = match[1].replace(assetPath, replacementPath); + var replaceString; - if (this.prepend && replaceString.indexOf(this.prepend) !== 0) { - var removeLeadingRelativeOrSlashRegex = new RegExp('^(\\.*/)*(.*)$'); - replaceString = this.prepend + removeLeadingRelativeOrSlashRegex.exec(replaceString)[2]; + if (this.prepend) { + replaceString = match[1].replace(new RegExp('(\\.*/)*' + assetPath, 'g'), + replacer(replacementPath, this.prepend)); + } else { + replaceString = match[1].replace(new RegExp(assetPath, 'g'), replacementPath); } newString = newString.replace(new RegExp(escapeRegExp(match[1]), 'g'), replaceString); diff --git a/tests/filter-tests.js b/tests/filter-tests.js index ea3f3eb..06a264b 100644 --- a/tests/filter-tests.js +++ b/tests/filter-tests.js @@ -233,6 +233,39 @@ describe('broccoli-asset-rev', function() { }) }); + it('replaces assets in srcset attributes', function(){ + var sourcePath = 'tests/fixtures/srcset'; + var node = AssetRewrite(sourcePath + '/input', { + assetMap: { + '/assets/img/small.png': '/assets/img/other-small.png', + '/assets/img/medium.png': '/assets/img/other-medium.png', + '/assets/img/big.png': '/assets/img/other-big.png' + } + }); + + builder = new broccoli.Builder(node); + return builder.build().then(function(graph) { + confirmOutput(graph.directory, sourcePath + '/output'); + }); + }); + + it('replaces assets in srcset attributes with prepend option', function(){ + var sourcePath = 'tests/fixtures/srcset-prepend'; + var node = AssetRewrite(sourcePath + '/input', { + assetMap: { + '/assets/img/small.png': '/assets/img/other-small.png', + '/assets/img/medium.png': '/assets/img/other-medium.png', + '/assets/img/big.png': '/assets/img/other-big.png' + }, + prepend: 'https://subdomain.cloudfront.net/' + }); + + builder = new broccoli.Builder(node); + return builder.build().then(function(graph) { + confirmOutput(graph.directory, sourcePath + '/output'); + }); + }); + it('ignores JavaScript comments with URLs', function () { var sourcePath = 'tests/fixtures/js-comment'; var node = new AssetRewrite(sourcePath + '/input', { diff --git a/tests/fixtures/srcset-prepend/input/img.html b/tests/fixtures/srcset-prepend/input/img.html new file mode 100644 index 0000000..a5944be --- /dev/null +++ b/tests/fixtures/srcset-prepend/input/img.html @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/tests/fixtures/srcset-prepend/output/img.html b/tests/fixtures/srcset-prepend/output/img.html new file mode 100644 index 0000000..5d403dd --- /dev/null +++ b/tests/fixtures/srcset-prepend/output/img.html @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/tests/fixtures/srcset/input/img.html b/tests/fixtures/srcset/input/img.html new file mode 100644 index 0000000..99dc524 --- /dev/null +++ b/tests/fixtures/srcset/input/img.html @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/tests/fixtures/srcset/output/img.html b/tests/fixtures/srcset/output/img.html new file mode 100644 index 0000000..e147545 --- /dev/null +++ b/tests/fixtures/srcset/output/img.html @@ -0,0 +1,2 @@ + \ No newline at end of file