diff --git a/Gruntfile.js b/Gruntfile.js index 37e2c3e..626b5ed 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ module.exports = function(grunt) { grunt.initConfig({ // Metadata. meta: { - version: '3.0.0' + version: '3.1.0' }, banner: '/*! picturePolyfill - v<%= meta.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %>\n' + diff --git a/README.md b/README.md index ce70ee3..5cbdf6b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# picturePolyfill 3 +# picturePolyfill 3.1 A Responsive Images approach that you can use today that uses the **[real `picture` element](http://www.w3.org/TR/2013/WD-html-picture-element-20130226/)** along with children `source` elements with `media`, `src` and `srcset` attributes. diff --git a/bower.json b/bower.json index 17f39a8..f511473 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "picturePolyfill", - "version": "3.0.0", + "version": "3.1.0", "main": "picturePolyfill.js", "ignore": [ ".idea", diff --git a/picturePolyfill.js b/picturePolyfill.js index 5595ec3..a4b5854 100644 --- a/picturePolyfill.js +++ b/picturePolyfill.js @@ -110,66 +110,59 @@ var picturePolyfill = (function(w) { }, /** - * Returns a hash density > sourceSet + * Returns a sorted array of object representing the elements of a srcset attribute, + * where pxr is the pixel ratio and src is the source for that ratio * @param srcset - * @returns {{}} + * @returns {Array} * @private */ - _getSrcsetHash: function(srcset) { + _getSrcsetArray: function(srcset) { var srcSetElement, source, density, - hash = {}, + ret = [], srcSetElements = srcset.split(','); for (var i=0, len=srcSetElements.length; i pxr2) { return 1; } + return 0; + }); }, /** - * Returns the proper src from the srcSet property + * Returns the proper src from the srcset array obtained by _getSrcsetArray * Get the first valid element from passed position to the left - * @param srcsetHash - * @param position - * @returns {*} + * @param array + * @param pixelRatio + * @returns string || null * @private */ - _getSrcFromHash: function(srcsetHash, position) { - var ret, key; - - // Try direct access to position - best case - ret = srcsetHash[position+'x']; - if (ret) { return ret; } - - // Try looking for smaller images + _getSrcFromArray: function(array, pixelRatio) { + var i=0, + len = array.length, + breakPoint=-1; + if (!len) { return null; } do { - position-=1; - ret = srcsetHash[position+'x']; - } - while (!ret && position>0); - if (ret) { return ret; } - - // Still nothing? Get the first result in the hash and return it - for (key in srcsetHash) { - return srcsetHash[key]; - } - - // Fallback - return null; + if (array[i].pxr >= pixelRatio || i === len-1) { + breakPoint = i; + } + i+=1; + } while (!(breakPoint > -1 || i >= len)); + return array[breakPoint].src; }, /** @@ -190,7 +183,7 @@ var picturePolyfill = (function(w) { media = sourceData.media; srcset = sourceData.srcset; if (!media || w.matchMedia(media).matches) { - matchedSrc = srcset ? this._getSrcFromHash(srcset, this._pxRatio) : sourceData.src; + matchedSrc = srcset ? this._getSrcFromArray(srcset, this._pxRatio) : sourceData.src; } } return matchedSrc; @@ -235,7 +228,7 @@ var picturePolyfill = (function(w) { sourceElement = foundSources[i]; sourceData = this._getAttrs(sourceElement, this._getAttrsList(sourceElement)); if (sourceData.srcset) { - sourceData.srcset = this._getSrcsetHash(sourceData.srcset); + sourceData.srcset = this._getSrcsetArray(sourceData.srcset); } sourcesData.push(sourceData); } @@ -287,7 +280,7 @@ var picturePolyfill = (function(w) { * @type {number} * @private */ - this._pxRatio = (w.devicePixelRatio) ? Math.ceil(w.devicePixelRatio) : 1; + this._pxRatio = w.devicePixelRatio || 1; /** * Detect if browser has media queries support diff --git a/picturePolyfill.min.js b/picturePolyfill.min.js index cf7f812..7430f0c 100644 --- a/picturePolyfill.min.js +++ b/picturePolyfill.min.js @@ -1,4 +1,4 @@ -/*! picturePolyfill - v3.0.0 - 2014-03-31 +/*! picturePolyfill - v3.1.0 - 2014-04-05 * https://github.com/verlok/picturePolyfill/ * Copyright (c) 2014 Andrea "verlok" Verlicchi; Licensed MIT */ -var picturePolyfill=function(a){"use strict";function b(){var a,b,c=document.createElement("img");if(a=document.getElementsByTagName("picture"),b=a[0],!a.length)return!1;try{return b.appendChild(c),b.removeChild(c),!0}catch(d){return!1}}var c,d,e,f=100,g=!1;return{_appendImg:function(a,b){var c=document.createElement("img");this._setAttrs(c,b),a.appendChild(c)},_setAttrs:function(a,b){for(var c in b)a.setAttribute(c,b[c])},_getAttrs:function(a,b){for(var c,d,e={},f=0,g=b.length;g>f;f+=1)c=b[f],d=a.getAttribute(c),d&&(e[c]=d);return e},_getAttrsList:function(a){for(var b=[],c=0,d=a.attributes,e=d.length;e>c;c++)b.push(d.item(c).nodeName);return b},_replacePicture:function(a,b){var c=document.createElement("picture"),d=this._getAttrs(a,this._getAttrsList(a));this._appendImg(c,b),this._setAttrs(c,d),a.parentNode.replaceChild(c,a)},_getSrcsetHash:function(a){for(var b,c,d,e={},f=a.split(","),g=0,h=f.length;h>g;g+=1){switch(b=f[g].trim().split(" "),b.length){case 1:d="1x";break;case 2:d=b[1];break;default:d=b[b.length-1]}c=b[0],e[d]=c}return e},_getSrcFromHash:function(a,b){var c,d;if(c=a[b+"x"])return c;do b-=1,c=a[b+"x"];while(!c&&b>0);if(c)return c;for(d in a)return a[d];return null},_getSrcFromData:function(b){for(var c,d,e,f,g=0,h=b.length;h>g;g+=1)d=b[g],e=d.media,f=d.srcset,(!e||a.matchMedia(e).matches)&&(c=f?this._getSrcFromHash(f,this._pxRatio):d.src);return c},_setImg:function(a,b){var c=a.getElementsByTagName("img");c.length?c[0].setAttribute("src",b.src):this._appendSupport?this._appendImg(a,b):this._replacePicture(a,b)},_getSourcesData:function(a){for(var b,c,d=[],e=a.getElementsByTagName("source"),f=0,g=e.length;g>f;f+=1)b=e[f],c=this._getAttrs(b,this._getAttrsList(b)),c.srcset&&(c.srcset=this._getSrcsetHash(c.srcset)),d.push(c);return d},_addListeners:function(){function b(){picturePolyfill.parse(document)}function c(){clearTimeout(e),e=setTimeout(b,f)}return!this.isUseful||g?!1:(a.addEventListener?(a.addEventListener("resize",c),a.addEventListener("DOMContentLoaded",function(){b(),a.removeEventListener("load",b)}),a.addEventListener("load",b)):a.attachEvent&&(a.attachEvent("onload",b),a.attachEvent("onresize",c)),void(g=!0))},initialize:function(){this._pxRatio=a.devicePixelRatio?Math.ceil(a.devicePixelRatio):1,this._mqSupport=!!a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,this._appendSupport=b(),this.isUseful=!a.HTMLPictureElement,c=[],d=0,this._addListeners()},parse:function(a){var b,e,f,g;if(!this.isUseful)return 0;f=(a||document).getElementsByTagName("picture");for(var h=0,i=f.length;i>h;h+=1)e=f[h],this._mqSupport?(b=c[e.getAttribute("data-cache-index")],b||(b=this._getSourcesData(e),c[d]=b,e.setAttribute("data-cache-index",d),d+=1),g=this._getSrcFromData(b)):g=e.getAttribute("data-default-src"),this._setImg(e,{src:g,alt:e.getAttribute("data-alt")});return h}}}(window);picturePolyfill.initialize(); \ No newline at end of file +var picturePolyfill=function(a){"use strict";function b(){var a,b,c=document.createElement("img");if(a=document.getElementsByTagName("picture"),b=a[0],!a.length)return!1;try{return b.appendChild(c),b.removeChild(c),!0}catch(d){return!1}}var c,d,e,f=100,g=!1;return{_appendImg:function(a,b){var c=document.createElement("img");this._setAttrs(c,b),a.appendChild(c)},_setAttrs:function(a,b){for(var c in b)a.setAttribute(c,b[c])},_getAttrs:function(a,b){for(var c,d,e={},f=0,g=b.length;g>f;f+=1)c=b[f],d=a.getAttribute(c),d&&(e[c]=d);return e},_getAttrsList:function(a){for(var b=[],c=0,d=a.attributes,e=d.length;e>c;c++)b.push(d.item(c).nodeName);return b},_replacePicture:function(a,b){var c=document.createElement("picture"),d=this._getAttrs(a,this._getAttrsList(a));this._appendImg(c,b),this._setAttrs(c,d),a.parentNode.replaceChild(c,a)},_getSrcsetArray:function(a){for(var b,c,d,e=[],f=a.split(","),g=0,h=f.length;h>g;g+=1)b=f[g].trim().split(" "),d=1===b.length?1:parseFloat(b[b.length-1],10),c=b[0],e.push({pxr:d,src:c});return e.sort(function(a,b){var c=a.pxr,d=b.pxr;return d>c?-1:c>d?1:0})},_getSrcFromArray:function(a,b){var c=0,d=a.length,e=-1;if(!d)return null;do(a[c].pxr>=b||c===d-1)&&(e=c),c+=1;while(!(e>-1||c>=d));return a[e].src},_getSrcFromData:function(b){for(var c,d,e,f,g=0,h=b.length;h>g;g+=1)d=b[g],e=d.media,f=d.srcset,(!e||a.matchMedia(e).matches)&&(c=f?this._getSrcFromArray(f,this._pxRatio):d.src);return c},_setImg:function(a,b){var c=a.getElementsByTagName("img");c.length?c[0].setAttribute("src",b.src):this._appendSupport?this._appendImg(a,b):this._replacePicture(a,b)},_getSourcesData:function(a){for(var b,c,d=[],e=a.getElementsByTagName("source"),f=0,g=e.length;g>f;f+=1)b=e[f],c=this._getAttrs(b,this._getAttrsList(b)),c.srcset&&(c.srcset=this._getSrcsetArray(c.srcset)),d.push(c);return d},_addListeners:function(){function b(){picturePolyfill.parse(document)}function c(){clearTimeout(e),e=setTimeout(b,f)}return!this.isUseful||g?!1:(a.addEventListener?(a.addEventListener("resize",c),a.addEventListener("DOMContentLoaded",function(){b(),a.removeEventListener("load",b)}),a.addEventListener("load",b)):a.attachEvent&&(a.attachEvent("onload",b),a.attachEvent("onresize",c)),void(g=!0))},initialize:function(){this._pxRatio=a.devicePixelRatio||1,this._mqSupport=!!a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,this._appendSupport=b(),this.isUseful=!a.HTMLPictureElement,c=[],d=0,this._addListeners()},parse:function(a){var b,e,f,g;if(!this.isUseful)return 0;f=(a||document).getElementsByTagName("picture");for(var h=0,i=f.length;i>h;h+=1)e=f[h],this._mqSupport?(b=c[e.getAttribute("data-cache-index")],b||(b=this._getSourcesData(e),c[d]=b,e.setAttribute("data-cache-index",d),d+=1),g=this._getSrcFromData(b)):g=e.getAttribute("data-default-src"),this._setImg(e,{src:g,alt:e.getAttribute("data-alt")});return h}}}(window);picturePolyfill.initialize(); \ No newline at end of file diff --git a/test/picturePolyfill.qunit.js b/test/picturePolyfill.qunit.js index c6ec954..b12a261 100644 --- a/test/picturePolyfill.qunit.js +++ b/test/picturePolyfill.qunit.js @@ -22,135 +22,177 @@ test("main object is declared and exposed", function() { strictEqual(typeof window.picturePolyfill.initialize, 'function', "picturePolyfill.initialize() should be a function") }); -test("_getSrcFromHash correct behaviour, correct data", function() { - var srcsetHash; +test("_getSrcFromArray correct behaviour, correct data, correct calls", function() { + var srcsetArray; // Get 1, 2 or 3 from 1x, 2x, 3x hash - srcsetHash = { - "1x": "http://placehold.it/4x4", - "2x": "http://placehold.it/8x8", - "3x": "http://placehold.it/12x12" - }; + srcsetArray = [ + {"pxr":0.25, "src":"http://placehold.it/1x1"}, + {"pxr":0.5, "src":"http://placehold.it/2x2"}, + {"pxr":1, "src":"http://placehold.it/4x4"}, + {"pxr":1.5, "src":"http://placehold.it/6x6"}, + {"pxr":2, "src":"http://placehold.it/8x8"}, + {"pxr":2.5, "src":"http://placehold.it/10x10"}, + {"pxr":3, "src":"http://placehold.it/12x12"} + ]; // Correct calls - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 1), 'http://placehold.it/4x4', "Single density element doesn't match"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 2), 'http://placehold.it/8x8', "Double density element doesn't match"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 3), 'http://placehold.it/12x12', "Triple density element doesn't match"); - // Extra bounds calls - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 4), 'http://placehold.it/12x12', "Out of upper bound call should return upper in-bound value"); - // Impossible calls (.5 is rounded to 1, <1 is impossible) - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, .5), 'http://placehold.it/4x4', "Impossible density should return lower bound value"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, -1), 'http://placehold.it/4x4', "Out or lower bound call should return lower in-bound value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 1), 'http://placehold.it/4x4', "Single density element doesn't match"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 1.5), 'http://placehold.it/6x6', "1.5 density element doesn't match"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 2), 'http://placehold.it/8x8', "Double density element doesn't match"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 3), 'http://placehold.it/12x12', "Triple density element doesn't match"); }); -test("_getSrcFromHash correct behaviour, missing middle data", function() { - var srcsetHash; +test("_getSrcFromArray correct behaviour, correct data, out of bound calls", function() { + var srcsetArray; // Get 1, 2 or 3 from 1x, 3x hash - srcsetHash = { - "1x": "http://placehold.it/4x4", - "3x": "http://placehold.it/12x12" - }; - // Correct calls - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 1), 'http://placehold.it/4x4', "Single density element doesn't match"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 3), 'http://placehold.it/12x12', "Triple density element doesn't match"); + srcsetArray = [ + {"pxr":1, "src":"http://placehold.it/4x4"}, + {"pxr":2, "src":"http://placehold.it/8x8"}, + {"pxr":3, "src":"http://placehold.it/12x12"} + ]; // Extra bounds calls - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 4), 'http://placehold.it/12x12', "Out of upper bound call should return upper in-bound value"); - // In the hole call - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 2), 'http://placehold.it/4x4', "Missing density item should return the lower value"); - // Impossible calls (.5 is rounded to 1, <1 is impossible) - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, .5), 'http://placehold.it/4x4', "Impossible density should return lower bound value"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, -1), 'http://placehold.it/4x4', "Out or lower bound call should return lower in-bound value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 3.5), 'http://placehold.it/12x12', "Out of upper bound call should return upper in-bound value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 4), 'http://placehold.it/12x12', "Out of upper bound call should return upper in-bound value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, .11), 'http://placehold.it/4x4', "Out of lower bound call should return lower in-bound value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, -1), 'http://placehold.it/4x4', "Out or lower bound call should return lower in-bound value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 0), 'http://placehold.it/4x4', "Out or lower bound call should return lower in-bound value"); }); -test("_getSrcFromHash correct behaviour, missing first data", function() { - var srcsetHash; +test("_getSrcFromArray correct behaviour, correct data, infra-bound calls", function() { + var srcsetArray; // Get 1, 2 or 3 from 1x, 3x hash - srcsetHash = { - "2x": "http://placehold.it/8x8", - "3x": "http://placehold.it/12x12" - }; - // Correct calls - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 2), 'http://placehold.it/8x8', "Double density element doesn't match"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 3), 'http://placehold.it/12x12', "Triple density element doesn't match"); - // Extra bounds calls - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 4), 'http://placehold.it/12x12', "Out of upper bound call should return upper in-bound value"); - // In the hole call - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 1), 'http://placehold.it/8x8', "Out or lower bound call should return lower in-bound value"); - // Impossible calls (.5 is rounded to 1, <1 is impossible) - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, .5), 'http://placehold.it/8x8', "Impossible density should return lower bound value"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, -1), 'http://placehold.it/8x8', "Out or lower bound call should return lower in-bound value");; + srcsetArray = [ + {"pxr":1, "src":"http://placehold.it/4x4"}, + {"pxr":2, "src":"http://placehold.it/8x8"}, + {"pxr":3, "src":"http://placehold.it/12x12"} + ]; + // Infra-bound calls + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 1.5), 'http://placehold.it/8x8', "Infra-bound call should return immediate upper value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 1.75), 'http://placehold.it/8x8', "Infra-bound call should return immediate upper value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 2.5), 'http://placehold.it/12x12', "Infra-bound call should return immediate upper value"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 2.25), 'http://placehold.it/12x12', "Infra-bound call should return immediate upper value"); }); -test("_getSrcFromHash correct behaviour, empty hash", function() { - var srcsetHash; +test("_getSrcFromArray correct behaviour, empty array", function() { + var srcsetArray; // Get 1, 2 or 3 from 1x, 3x hash - srcsetHash = {}; + srcsetArray = []; // Correct calls - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, -1), null, "If hash is empty, null value must be returned"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 0), null, "If hash is empty, null value must be returned"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 1), null, "If hash is empty, null value must be returned"); - strictEqual(picturePolyfill._getSrcFromHash(srcsetHash, 2), null, "If hash is empty, null value must be returned"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, -1), null, "If array is empty, null value must be returned"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 0), null, "If array is empty, null value must be returned"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 1), null, "If array is empty, null value must be returned"); + strictEqual(picturePolyfill._getSrcFromArray(srcsetArray, 2), null, "If array is empty, null value must be returned"); }); -test("_getSrcsetHash correct behaviour, correct srcset format", function () { +test("_getSrcsetArray correct behaviour, correct srcset format", function () { if (!picturePolyfill._mqSupport) { ok(true); } else { - var srcset; + var srcset, expected; + // Single srcset = "http://placehold.it/4x4"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "1x": "http://placehold.it/4x4" - }); + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Srcset formatted like src should return a single element with ratio 1"); + // Single 2x - srcset = "http://placehold.it/4x4 2x"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "2x": "http://placehold.it/4x4" - }); + srcset = "http://placehold.it/8x8 2x"; + expected = [ + {pxr: 2, src: "http://placehold.it/8x8"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Single 2x input should return a single element with ratio 2"); + + // Double with 1x + srcset = "http://placehold.it/4x4 1x, http://placehold.it/8x8 2x"; + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"}, + {pxr: 2, src: "http://placehold.it/8x8"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Double with 1x"); + // Double srcset = "http://placehold.it/4x4, http://placehold.it/8x8 2x"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "1x": "http://placehold.it/4x4", - "2x": "http://placehold.it/8x8" - }); + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"}, + {pxr: 2, src: "http://placehold.it/8x8"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Double"); + // Triple srcset = "http://placehold.it/4x4, http://placehold.it/8x8 2x, http://placehold.it/12x12 3x"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "1x": "http://placehold.it/4x4", - "2x": "http://placehold.it/8x8", - "3x": "http://placehold.it/12x12" - }); + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"}, + {pxr: 2, src: "http://placehold.it/8x8"}, + {pxr: 3, src: "http://placehold.it/12x12"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Triple"); + + // Triple with decimals + srcset = "http://placehold.it/4x4, http://placehold.it/6x6 1.5x, http://placehold.it/8x8 2x"; + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"}, + {pxr: 1.5, src: "http://placehold.it/6x6"}, + {pxr: 2, src: "http://placehold.it/8x8"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Triple with decimals"); + // Double with 1x and 3x srcset = "http://placehold.it/4x4, http://placehold.it/12x12 3x"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "1x": "http://placehold.it/4x4", - "3x": "http://placehold.it/12x12" - }); + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"}, + {pxr: 3, src: "http://placehold.it/12x12"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Double with 1x and 3x"); + + // Double with .5x and 1x + srcset = "http://placehold.it/2x2 .5x, http://placehold.it/4x4"; + expected = [ + {pxr: 0.5, src: "http://placehold.it/2x2"}, + {pxr: 1, src: "http://placehold.it/4x4"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Double with .5x and 1x"); + + // Double with 0.5x and 1x, leading 0 + srcset = "http://placehold.it/2x2 0.5x, http://placehold.it/4x4"; + expected = [ + {pxr: 0.5, src: "http://placehold.it/2x2"}, + {pxr: 1, src: "http://placehold.it/4x4"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Double with 0.5x and 1x, leading 0"); } }); -test("_getSrcsetHash correct behaviour, messy srcset format", function () { +test("_getSrcsetArray correct behaviour, messy srcset format", function () { if (!picturePolyfill._mqSupport) { ok(true); } else { - var srcset; - // Double with 1x and 2x -- EXTRA SPACES IN MIDDLE - srcset = "http://placehold.it/4x4, http://placehold.it/8x8 2x"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "1x": "http://placehold.it/4x4", - "2x": "http://placehold.it/8x8" - }); - // Triple with 1x and 3x -- EXTRA SPACES EVERYWHERE + var srcset, expected; + + // Double with 1x and 2x -- EXTRA SPACES IN THE MIDDLE + srcset = "http://placehold.it/4x4, http://placehold.it/8x8 2x"; + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"}, + {pxr: 2, src: "http://placehold.it/8x8"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Double with 1x and 2x -- EXTRA SPACES IN THE MIDDLE"); + + // Double with 1x and 3x -- EXTRA SPACES EVERYWHERE srcset = "http://placehold.it/4x4 , http://placehold.it/12x12 3x"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "1x": "http://placehold.it/4x4", - "3x": "http://placehold.it/12x12" - }); + expected = [ + {pxr: 1, src: "http://placehold.it/4x4"}, + {pxr: 3, src: "http://placehold.it/12x12"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Double with 1x and 3x -- EXTRA SPACES EVERYWHERE"); + // Single 2x with extra spaces - srcset = "http://placehold.it/8x8 2x"; - deepEqual(picturePolyfill._getSrcsetHash(srcset), { - "2x": "http://placehold.it/8x8" - }); + srcset = "http://placehold.it/8x8 2x"; + expected = [ + {pxr: 2, src: "http://placehold.it/8x8"} + ]; + deepEqual(picturePolyfill._getSrcsetArray(srcset), expected, "Single 2x with extra spaces"); } }); @@ -162,10 +204,10 @@ test("_getSrcFromData behaves correctly", function() { // Normal case var sourcesData = [ { - srcset: { - "1x": "a.gif", - "2x": "b.gif" - } + srcset: [ + {pxr: 1, src: "a.gif"}, + {pxr: 2, src: "b.gif"} + ] } ]; picturePolyfill._pxRatio = 1; @@ -177,10 +219,10 @@ test("_getSrcFromData behaves correctly", function() { // With more MQs sourcesData.push({ media: "(min-width: 1px)", - srcset: { - "1x": "c.gif", - "2x": "d.gif" - } + srcset: [ + {pxr: 1, src: "c.gif"}, + {pxr: 2, src: "d.gif"} + ] }); picturePolyfill._pxRatio = 1; strictEqual(picturePolyfill._getSrcFromData(sourcesData), "c.gif"); @@ -202,7 +244,7 @@ test("_getSourcesData correctly parses sources", function() {
\ \ \ - \ + \ \ \ \ @@ -226,8 +268,18 @@ test("_getSourcesData correctly parses sources", function() { pictureEl2 = document.getElementById('second'); // Set expectations - expected1 = [ { "srcset": { "1x": "http://placehold.it/4x4", "2x": "http://placehold.it/8x8" } }, { "media": "(min-width: 481px)", "srcset": { "1x": "http://placehold.it/5x5", "2x": "http://placehold.it/5x5" } }, { "media": "(min-width: 1025px)", "srcset": { "1x": "http://placehold.it/7x7", "2x": "http://placehold.it/14x14" } }, { "media": "(min-width: 1441px)", "srcset": { "1x": "http://placehold.it/9x9", "2x": "http://placehold.it/18x18" } } ]; - expected2 = [ { "src": "http://placehold.it/4x4" }, { "media": "(min-width: 481px)", "src": "http://placehold.it/5x5" }, { "media": "(min-width: 1025px)", "src": "http://placehold.it/7x7" }, { "media": "(min-width: 1441px)", "src": "http://placehold.it/9x9" } ]; + expected1 = [ + {"srcset": [{"pxr":1,"src":"http://placehold.it/4x4"}, {"pxr":2,"src":"http://placehold.it/8x8"}]}, + {"srcset": [{"pxr":1,"src":"http://placehold.it/5x5"}, {"pxr":2,"src":"http://placehold.it/10x10"}], "media":"(min-width: 481px)"}, + {"srcset": [{"pxr":1,"src":"http://placehold.it/7x7"}, {"pxr":2,"src":"http://placehold.it/14x14"}], "media":"(min-width: 1025px)"}, + {"srcset": [{"pxr":1,"src":"http://placehold.it/9x9"}, {"pxr":2,"src":"http://placehold.it/18x18"}], "media":"(min-width: 1441px)"} + ]; + expected2 = [ + {"src":"http://placehold.it/4x4"}, + {"src":"http://placehold.it/5x5", "media":"(min-width: 481px)"}, + {"src":"http://placehold.it/7x7", "media":"(min-width: 1025px)"}, + {"src":"http://placehold.it/9x9", "media":"(min-width: 1441px)"} + ]; // Get the results returned1 = picturePolyfill._getSourcesData(pictureEl1); @@ -488,7 +540,7 @@ test("parse() resulting image sources - without MQ support", function(){ }); -test("_getSourcesData, _getSrcFromData, _getSrcFromHash mustn't be called from non MQ browsers", function() { +test("_getSourcesData, _getSrcFromData, _getSrcFromArray mustn't be called from non MQ browsers", function() { $('body').append('
\ \ @@ -499,7 +551,7 @@ test("_getSourcesData, _getSrcFromData, _getSrcFromHash mustn't be called from n this.spy(picturePolyfill, "_getSourcesData"); this.spy(picturePolyfill, "_getSrcFromData"); - this.spy(picturePolyfill, "_getSrcFromHash"); + this.spy(picturePolyfill, "_getSrcFromArray"); picturePolyfill.initialize(); @@ -510,14 +562,14 @@ test("_getSourcesData, _getSrcFromData, _getSrcFromHash mustn't be called from n ok(picturePolyfill._getSourcesData.notCalled); ok(picturePolyfill._getSrcFromData.notCalled); - ok(picturePolyfill._getSrcFromHash.notCalled); + ok(picturePolyfill._getSrcFromArray.notCalled); if (initial_mqSupport) { picturePolyfill._mqSupport = true; picturePolyfill.parse(); ok(picturePolyfill._getSourcesData.called); ok(picturePolyfill._getSrcFromData.called); - ok(picturePolyfill._getSrcFromHash.called); + ok(picturePolyfill._getSrcFromArray.called); } picturePolyfill._mqSupport = initial_mqSupport;