Skip to content

Commit

Permalink
fix(buildSrcSet): ensure largest size can't be repeated
Browse files Browse the repository at this point in the history
The largest size was being repeated in certain conditions, since the
value stored in `prev` was exact (possibly fractional) while the number
saved in the list of resolutions is rounded to an even number, but the
value stored in `prev` was the one being compared to `maxWidth`.

In this fix we remove the code which pushes `maxWidth` to the list
*after* the loop finishes and compare the last value in the list to
`maxWidth` rather than the running exact fractional width value. These
together eliminate the areas where the bug can subtly appear. It is then
necessary to refactor the loop, by initializing the list to already
contain the `minWidth` and then exiting early if `maxWidth` is equal
(which has the side benefit that the cache won't be polluted with
trivial cases) and then in the loop body push the *new* rather than
previous value to the list, after rounding and clamping.
  • Loading branch information
tremby committed Nov 4, 2020
1 parent 0201b4f commit 76eac04
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions src/imgix-core-js.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,15 @@

// returns an array of width values used during scrset generation
ImgixClient.prototype._generateTargetWidths = function(widthTolerance, minWidth, maxWidth) {
var resolutions = [];
var resolutions = [minWidth];
var INCREMENT_PERCENTAGE = widthTolerance;
var minWidth = Math.floor(minWidth);
var maxWidth = Math.floor(maxWidth);

if (minWidth === maxWidth) {
return resolutions;
}

var cacheKey = INCREMENT_PERCENTAGE + '/' + minWidth + '/' + maxWidth;

if (cacheKey in this.targetWidthsCache) {
Expand All @@ -238,14 +243,12 @@
return 2 * Math.round(n / 2);
};

var prev = minWidth;
while (prev < maxWidth) {
resolutions.push(ensureEven(prev));
prev *= 1 + (INCREMENT_PERCENTAGE * 2);
var exact = minWidth;
while (resolutions[resolutions.length - 1] < maxWidth) {
exact *= 1 + (INCREMENT_PERCENTAGE * 2);
resolutions.push(Math.min(ensureEven(exact), maxWidth));
}

resolutions.push(maxWidth);

this.targetWidthsCache[cacheKey] = resolutions;

return resolutions;
Expand Down

0 comments on commit 76eac04

Please sign in to comment.