webshims-rails 1.15.6.4 → 1.15.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/lib/assets/javascripts/webshims/polyfiller.js +1 -1
  3. data/lib/assets/javascripts/webshims/shims/combos/1.js +1 -1
  4. data/lib/assets/javascripts/webshims/shims/combos/10.js +1 -1
  5. data/lib/assets/javascripts/webshims/shims/combos/11.js +1 -1
  6. data/lib/assets/javascripts/webshims/shims/combos/14.js +1 -1
  7. data/lib/assets/javascripts/webshims/shims/combos/15.js +2 -2
  8. data/lib/assets/javascripts/webshims/shims/combos/16.js +2 -2
  9. data/lib/assets/javascripts/webshims/shims/combos/17.js +2 -2
  10. data/lib/assets/javascripts/webshims/shims/combos/18.js +7 -3
  11. data/lib/assets/javascripts/webshims/shims/combos/2.js +2 -2
  12. data/lib/assets/javascripts/webshims/shims/combos/28.js +1 -1
  13. data/lib/assets/javascripts/webshims/shims/combos/3.js +1 -1
  14. data/lib/assets/javascripts/webshims/shims/combos/30.js +1 -1
  15. data/lib/assets/javascripts/webshims/shims/combos/31.js +1 -1
  16. data/lib/assets/javascripts/webshims/shims/combos/4.js +1 -1
  17. data/lib/assets/javascripts/webshims/shims/combos/5.js +2 -2
  18. data/lib/assets/javascripts/webshims/shims/combos/6.js +2 -2
  19. data/lib/assets/javascripts/webshims/shims/combos/7.js +2 -2
  20. data/lib/assets/javascripts/webshims/shims/combos/8.js +2 -2
  21. data/lib/assets/javascripts/webshims/shims/combos/9.js +1 -1
  22. data/lib/assets/javascripts/webshims/shims/form-combat.js +1 -1
  23. data/lib/assets/javascripts/webshims/shims/form-core.js +1 -1
  24. data/lib/assets/javascripts/webshims/shims/form-message.js +1 -1
  25. data/lib/assets/javascripts/webshims/shims/form-number-date-ui.js +1 -1
  26. data/lib/assets/javascripts/webshims/shims/form-validation.js +1 -1
  27. data/lib/assets/javascripts/webshims/shims/i18n/formcfg-bg.js +1 -0
  28. data/lib/assets/javascripts/webshims/shims/i18n/formcfg-en.js +1 -1
  29. data/lib/assets/javascripts/webshims/shims/i18n/formcfg-fi.js +1 -0
  30. data/lib/assets/javascripts/webshims/shims/i18n/formcfg-fr.js +1 -1
  31. data/lib/assets/javascripts/webshims/shims/picture.js +7 -3
  32. data/lib/assets/javascripts/webshims/shims/styles/forms-ext.css +1 -1
  33. data/lib/assets/javascripts/webshims/shims/styles/shim-ext.css +1 -1
  34. data/lib/webshims-rails/version.rb +2 -2
  35. data/vendor/assets/javascripts/webshims/polyfiller.js +4 -8
  36. data/vendor/assets/javascripts/webshims/shims/FlashCanvas/proxy.php +2 -2
  37. data/vendor/assets/javascripts/webshims/shims/FlashCanvasPro/proxy.php +2 -2
  38. data/vendor/assets/javascripts/webshims/shims/combos/1.js +5 -3
  39. data/vendor/assets/javascripts/webshims/shims/combos/10.js +19 -10
  40. data/vendor/assets/javascripts/webshims/shims/combos/11.js +19 -10
  41. data/vendor/assets/javascripts/webshims/shims/combos/14.js +3 -3
  42. data/vendor/assets/javascripts/webshims/shims/combos/15.js +9 -7
  43. data/vendor/assets/javascripts/webshims/shims/combos/16.js +10 -9
  44. data/vendor/assets/javascripts/webshims/shims/combos/17.js +19 -10
  45. data/vendor/assets/javascripts/webshims/shims/combos/18.js +1274 -319
  46. data/vendor/assets/javascripts/webshims/shims/combos/2.js +6 -5
  47. data/vendor/assets/javascripts/webshims/shims/combos/28.js +4 -4
  48. data/vendor/assets/javascripts/webshims/shims/combos/3.js +6 -4
  49. data/vendor/assets/javascripts/webshims/shims/combos/30.js +7 -5
  50. data/vendor/assets/javascripts/webshims/shims/combos/31.js +5 -3
  51. data/vendor/assets/javascripts/webshims/shims/combos/4.js +2 -2
  52. data/vendor/assets/javascripts/webshims/shims/combos/5.js +19 -10
  53. data/vendor/assets/javascripts/webshims/shims/combos/6.js +19 -10
  54. data/vendor/assets/javascripts/webshims/shims/combos/7.js +8 -7
  55. data/vendor/assets/javascripts/webshims/shims/combos/8.js +7 -6
  56. data/vendor/assets/javascripts/webshims/shims/combos/9.js +19 -10
  57. data/vendor/assets/javascripts/webshims/shims/combos/comboinfo.json +1 -1
  58. data/vendor/assets/javascripts/webshims/shims/form-combat.js +40 -23
  59. data/vendor/assets/javascripts/webshims/shims/form-core.js +3 -1
  60. data/vendor/assets/javascripts/webshims/shims/form-message.js +1 -1
  61. data/vendor/assets/javascripts/webshims/shims/form-number-date-ui.js +19 -10
  62. data/vendor/assets/javascripts/webshims/shims/form-validation.js +7 -2
  63. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-bg.js +130 -0
  64. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-en.js +4 -8
  65. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-fi.js +127 -0
  66. data/vendor/assets/javascripts/webshims/shims/i18n/formcfg-fr.js +2 -2
  67. data/vendor/assets/javascripts/webshims/shims/picture.js +1283 -328
  68. data/vendor/assets/javascripts/webshims/shims/styles/forms-ext.css +0 -6
  69. data/vendor/assets/javascripts/webshims/shims/styles/scss/forms-ext.scss +0 -14
  70. data/vendor/assets/javascripts/webshims/shims/styles/shim-ext.css +0 -6
  71. metadata +7 -3
@@ -38,8 +38,8 @@ webshims.validityMessages.fr = {
38
38
  };
39
39
  webshims.formcfg.fr = {
40
40
  numberFormat: {
41
- ".": ".",
42
- ",": ","
41
+ ".": ",",
42
+ ",": " "
43
43
  },
44
44
  numberSigns: '.',
45
45
  dateSigns: '/',
@@ -1,369 +1,1227 @@
1
- /*! respimage - v1.2.1 - 2014-12-23
2
- Licensed MIT */
3
- !function(window, document, undefined) {
1
+ /*! Respimg - Responsive Images that work today.
2
+ * Author: Alexander Farkas, 2014
3
+ * Author: Scott Jehl, Filament Group, 2012 ( new proposal implemented by Shawn Jansepar )
4
+ * License: MIT
5
+ * Spec: http://picture.responsiveimages.org/
6
+ */
7
+ (function( window, document, undefined ) {
8
+ // Enable strict mode
4
9
  "use strict";
5
- function trim(str) {
6
- return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, "");
10
+ if ( typeof RIDEBUG == "undefined" ) {
11
+ window.RIDEBUG = true;
7
12
  }
13
+
14
+ var lowTreshHold, partialLowTreshHold, isLandscape, lazyFactor, tMemory, substractCurRes, warn, eminpx,
15
+ alwaysCheckWDescriptor, resizeThrottle, evalID;
16
+ // local object for method references and testing exposure
17
+ var ri = {};
18
+ var noop = function() {};
19
+ var image = document.createElement( "img" );
20
+ var getImgAttr = image.getAttribute;
21
+ var setImgAttr = image.setAttribute;
22
+ var removeImgAttr = image.removeAttribute;
23
+ var docElem = document.documentElement;
24
+ var types = {};
25
+ var cfg = {
26
+ //resource selection:
27
+ xQuant: 1,
28
+ lazyFactor: 0.4,
29
+ maxX: 2
30
+ };
31
+ var srcAttr = "data-risrc";
32
+ var srcsetAttr = srcAttr + "set";
33
+ var reflowBug = "webkitBackfaceVisibility" in docElem.style;
34
+ var ua = navigator.userAgent;
35
+ var supportAbort = (/rident/).test(ua) || ((/ecko/).test(ua) && ua.match(/rv\:(\d+)/) && RegExp.$1 > 35 );
36
+ var curSrcProp = "currentSrc";
37
+ var regWDesc = /\s+\+?\d+(e\d+)?w/;
38
+ var regSize = /((?:\([^)]+\)(?:\s*and\s*|\s*or\s*|\s*not\s*)?)+)?\s*(.+)/;
39
+ var regDescriptor = /^([\+eE\d\.]+)(w|x)$/; // currently no h
40
+ var regHDesc = /\s*\d+h\s*/;
41
+ var setOptions = window.respimgCFG;
42
+ /**
43
+ * Shortcut property for https://w3c.github.io/webappsec/specs/mixedcontent/#restricts-mixed-content ( for easy overriding in tests )
44
+ */
45
+ var isSSL = location.protocol == "https:";
46
+ // baseStyle also used by getEmValue (i.e.: width: 1em is important)
47
+ var baseStyle = "position:absolute;left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;overflow:hidden;clip:rect(0px, 0px, 0px, 0px)";
48
+ var fsCss = "font-size:100%!important;";
49
+ var isVwDirty = true;
50
+
51
+ var cssCache = {};
52
+ var sizeLengthCache = {};
53
+ var DPR = window.devicePixelRatio;
54
+ var units = {
55
+ px: 1,
56
+ 'in': 96
57
+ };
58
+ var anchor = document.createElement( "a" );
59
+ /**
60
+ * alreadyRun flag used for setOptions. is it true setOptions will reevaluate
61
+ * @type {boolean}
62
+ */
63
+ var alreadyRun = false;
64
+
65
+ var on = function(obj, evt, fn, capture) {
66
+ if ( obj.addEventListener ) {
67
+ obj.addEventListener(evt, fn, capture || false);
68
+ } else if ( obj.attachEvent ) {
69
+ obj.attachEvent( "on"+ evt, fn);
70
+ }
71
+ };
72
+
73
+ var off = function(obj, evt, fn, capture) {
74
+ if ( obj.removeEventListener ) {
75
+ obj.removeEventListener(evt, fn, capture || false);
76
+ } else if ( obj.detachEvent ) {
77
+ obj.detachEvent( "on"+ evt, fn);
78
+ }
79
+ };
80
+
81
+ /**
82
+ * simple memoize function:
83
+ */
84
+
85
+ var memoize = function(fn) {
86
+ var cache = {};
87
+ return function(input) {
88
+ if ( !(input in cache) ) {
89
+ cache[ input ] = fn(input);
90
+ }
91
+ return cache[ input ];
92
+ };
93
+ };
94
+
95
+ /**
96
+ * gets a mediaquery and returns a boolean or gets a css length and returns a number
97
+ * @param css mediaqueries or css length
98
+ * @returns {boolean|number}
99
+ *
100
+ * based on: https://gist.github.com/jonathantneal/db4f77009b155f083738
101
+ */
102
+ var evalCSS = (function(){
103
+ var regLength = /^([\d\.]+)(em|vw|px)$/;
104
+ var replace = function() {
105
+ var args = arguments, index = 0, string = args[0];
106
+ while (++index in args) {
107
+ string = string.replace(args[index], args[++index]);
108
+ }
109
+ return string;
110
+ };
111
+
112
+ var buidlStr = memoize(function(css) {
113
+ return "return " + replace((css || "").toLowerCase(),
114
+ // interpret `and`
115
+ /\band\b/g, "&&",
116
+
117
+ // interpret `,`
118
+ /,/g, "||",
119
+
120
+ // interpret `min-` as >=
121
+ /min-([a-z-\s]+):/g, "e.$1>=",
122
+
123
+ // interpret `min-` as <=
124
+ /max-([a-z-\s]+):/g, "e.$1<=",
125
+
126
+ //calc value
127
+ /calc([^)]+)/g, "($1)",
128
+
129
+ // interpret css values
130
+ /(\d+[\.]*[\d]*)([a-z]+)/g, "($1 * e.$2)",
131
+ //make eval less evil
132
+ /^(?!(e.[a-z]|[0-9\.&=|><\+\-\*\(\)\/])).*/ig, ""
133
+ );
134
+ });
135
+
136
+ return function(css, length) {
137
+ var parsedLength;
138
+ if (!(css in cssCache)) {
139
+ cssCache[css] = false;
140
+ if(length && (parsedLength = css.match( regLength ))){
141
+ cssCache[css] = parsedLength[ 1 ] * units[parsedLength[ 2 ]];
142
+ } else {
143
+ /*jshint evil:true */
144
+ try{
145
+ cssCache[css] = new Function("e", buidlStr(css))(units);
146
+ } catch(e){}
147
+ /*jshint evil:false */
148
+ }
149
+ }
150
+ return cssCache[css];
151
+ };
152
+ })();
153
+
154
+ var setResolution = function ( candidate, sizesattr ) {
155
+ if ( candidate.w ) { // h = means height: || descriptor.type == 'h' do not handle yet...
156
+ candidate.cWidth = ri.calcListLength( sizesattr || "100vw" );
157
+ candidate.res = candidate.w / candidate.cWidth ;
158
+ } else {
159
+ candidate.res = candidate.x;
160
+ }
161
+ return candidate;
162
+ };
163
+
164
+ /**
165
+ *
166
+ * @param opt
167
+ */
168
+ var respimage = function( opt ) {
169
+ var elements, i, plen;
170
+
171
+ var options = opt || {};
172
+
173
+ if ( options.elements && options.elements.nodeType == 1 ) {
174
+ if ( options.elements.nodeName.toUpperCase() == "IMG" ) {
175
+ options.elements = [ options.elements ];
176
+ } else {
177
+ options.context = options.elements;
178
+ options.elements = null;
179
+ }
180
+ }
181
+
182
+ if(options.reparse){
183
+ options.reevaluate = true;
184
+ if(window.console && console.warn){
185
+ console.warn('reparse was renamed to reevaluate!');
186
+ }
187
+ }
188
+
189
+ elements = options.elements || ri.qsa( (options.context || document), ( options.reevaluate || options.reselect ) ? ri.sel : ri.selShort );
190
+
191
+ if ( (plen = elements.length) ) {
192
+
193
+ ri.setupRun( options );
194
+ alreadyRun = true;
195
+
196
+ // Loop through all elements
197
+
198
+ for ( i = 0; i < plen; i++ ) {
199
+ ri.fillImg(elements[ i ], options);
200
+ }
201
+ ri.teardownRun( options );
202
+ }
203
+ };
204
+
205
+ var parseDescriptor = memoize(function ( descriptor ) {
206
+
207
+ var descriptorObj = [1, 'x'];
208
+ var parsedDescriptor = trim( descriptor || "" );
209
+
210
+ if ( parsedDescriptor ) {
211
+ parsedDescriptor = parsedDescriptor.replace(regHDesc, "");
212
+ if ( ( parsedDescriptor ).match( regDescriptor ) ) {
213
+
214
+ descriptorObj = [RegExp.$1 * 1, RegExp.$2];
215
+
216
+ if ( RIDEBUG && (
217
+ descriptorObj[0] < 0 ||
218
+ isNaN( descriptorObj[0] ) ||
219
+ (descriptorObj[1] == "w" && /\./.test(''+descriptorObj[0]))
220
+ ) ) {
221
+ warn( "bad descriptor: " + descriptor );
222
+ }
223
+ } else {
224
+ descriptorObj = false;
225
+
226
+ if ( RIDEBUG ) {
227
+ warn( "unknown descriptor: " + descriptor );
228
+ }
229
+ }
230
+ }
231
+
232
+ return descriptorObj;
233
+ });
234
+
235
+ /**
236
+ * outputs a warning for the developer
237
+ * @param {message}
238
+ * @type {Function}
239
+ */
240
+ if(RIDEBUG){
241
+ warn = ( window.console && console.warn ) ?
242
+ function( message ) {
243
+ console.warn( message );
244
+ } :
245
+ noop
246
+ ;
247
+ }
248
+
249
+ if( !(curSrcProp in image) ){
250
+ curSrcProp = "src";
251
+ }
252
+
253
+ // Add support for standard mime types.
254
+ types["image/jpeg"] = true;
255
+ types["image/gif"] = true;
256
+ types["image/png"] = true;
257
+
258
+ // test svg support
259
+ types[ "image/svg+xml" ] = document.implementation.hasFeature( "http://wwwindow.w3.org/TR/SVG11/feature#Image", "1.1" );
260
+
261
+ /**
262
+ * a trim workaroung mainly for IE8
263
+ * @param str
264
+ * @returns {string}
265
+ */
266
+ function trim( str ) {
267
+ return str.trim ? str.trim() : str.replace( /^\s+|\s+$/g, "" );
268
+ }
269
+
270
+ /**
271
+ * updates the internal vW property with the current viewport width in px
272
+ */
8
273
  function updateMetrics() {
9
274
  var dprM;
10
- isVwDirty = !1, DPR = window.devicePixelRatio, cssCache = {}, sizeLengthCache = {},
11
- dprM = (DPR || 1) * cfg.xQuant, cfg.uT || (cfg.maxX = Math.max(1.3, cfg.maxX), dprM = Math.min(dprM, cfg.maxX),
12
- ri.DPR = dprM), units.width = Math.max(window.innerWidth || 0, docElem.clientWidth),
13
- units.height = Math.max(window.innerHeight || 0, docElem.clientHeight), units.vw = units.width / 100,
14
- units.vh = units.height / 100, units.em = ri.getEmValue(), units.rem = units.em,
15
- lazyFactor = cfg.lazyFactor / 2, lazyFactor = lazyFactor * dprM + lazyFactor, substractCurRes = .1 * dprM,
16
- lowTreshHold = .5 + .2 * dprM, partialLowTreshHold = .5 + .25 * dprM, tMemory = dprM + 1.3,
17
- (isLandscape = units.width > units.height) || (lazyFactor *= .9), supportAbort && (lazyFactor *= .9);
18
- }
19
- function chooseLowRes(lowRes, diff, dpr) {
20
- var add = diff * Math.pow(lowRes, 2);
21
- return isLandscape || (add /= 1.3), lowRes += add, lowRes > dpr;
275
+
276
+ isVwDirty = false;
277
+ DPR = window.devicePixelRatio;
278
+ cssCache = {};
279
+ sizeLengthCache = {};
280
+
281
+ dprM = (DPR || 1) * cfg.xQuant;
282
+
283
+ if(!cfg.uT){
284
+ cfg.maxX = Math.max(1.3, cfg.maxX);
285
+ dprM = Math.min( dprM, cfg.maxX );
286
+
287
+ ri.DPR = dprM;
288
+ }
289
+
290
+ units.width = Math.max(window.innerWidth || 0, docElem.clientWidth);
291
+ units.height = Math.max(window.innerHeight || 0, docElem.clientHeight);
292
+
293
+ units.vw = units.width / 100;
294
+ units.vh = units.height / 100;
295
+
296
+ units.em = ri.getEmValue();
297
+ units.rem = units.em;
298
+
299
+ lazyFactor = cfg.lazyFactor / 2;
300
+
301
+ lazyFactor = (lazyFactor * dprM) + lazyFactor;
302
+
303
+ substractCurRes = 0.4 + (0.1 * dprM);
304
+
305
+ lowTreshHold = 0.5 + (0.2 * dprM);
306
+
307
+ partialLowTreshHold = 0.5 + (0.25 * dprM);
308
+
309
+ tMemory = dprM + 1.3;
310
+
311
+ if(!(isLandscape = units.width > units.height)){
312
+ lazyFactor *= 0.9;
313
+ }
314
+ if(supportAbort){
315
+ lazyFactor *= 0.9;
316
+ }
317
+
318
+ evalID = [units.width, units.height, dprM].join('-');
22
319
  }
23
- function inView(el) {
24
- if (!el.getBoundingClientRect) return !0;
25
- var bottom, right, left, top, rect = el.getBoundingClientRect();
26
- return !!((bottom = rect.bottom) >= -9 && (top = rect.top) <= units.height + 9 && (right = rect.right) >= -9 && (left = rect.left) <= units.height + 9 && (bottom || right || left || top));
320
+
321
+ function chooseLowRes( lowRes, diff, dpr ) {
322
+ var add = diff * Math.pow(lowRes - 0.4, 1.9);
323
+ if(!isLandscape){
324
+ add /= 1.3;
325
+ }
326
+
327
+ lowRes += add;
328
+ return lowRes > dpr;
27
329
  }
28
- function applyBestCandidate(img) {
29
- var srcSetCandidates, matchingSet = ri.getSet(img), evaluated = !1;
30
- "pending" != matchingSet && (evaluated = !0, matchingSet && (srcSetCandidates = ri.setRes(matchingSet),
31
- evaluated = ri.applySetCandidate(srcSetCandidates, img))), img[ri.ns].evaled = evaluated;
330
+
331
+ function applyBestCandidate( img ) {
332
+ var srcSetCandidates;
333
+ var matchingSet = ri.getSet( img );
334
+ var evaluated = false;
335
+ if ( matchingSet != "pending" ) {
336
+ evaluated = evalID;
337
+ if ( matchingSet ) {
338
+ srcSetCandidates = ri.setRes( matchingSet );
339
+ evaluated = ri.applySetCandidate( srcSetCandidates, img );
340
+ }
341
+
342
+ }
343
+ img[ ri.ns ].evaled = evaluated;
32
344
  }
33
- function ascendingSort(a, b) {
345
+
346
+ function ascendingSort( a, b ) {
34
347
  return a.res - b.res;
35
348
  }
36
- function setSrcToCur(img, src, set) {
349
+
350
+ function setSrcToCur( img, src, set ) {
37
351
  var candidate;
38
- return !set && src && (set = img[ri.ns].sets, set = set && set[set.length - 1]),
39
- candidate = getCandidateForSrc(src, set), candidate && (src = ri.makeUrl(src), img[ri.ns].curSrc = src,
40
- img[ri.ns].curCan = candidate, candidate.res || setResolution(candidate, candidate.set.sizes)),
41
- candidate;
352
+ if ( !set && src ) {
353
+ set = img[ ri.ns ].sets;
354
+ set = set && set[set.length - 1];
355
+ }
356
+
357
+ candidate = getCandidateForSrc(src, set);
358
+
359
+ if ( candidate ) {
360
+ src = ri.makeUrl(src);
361
+ img[ ri.ns ].curSrc = src;
362
+ img[ ri.ns ].curCan = candidate;
363
+
364
+ if ( !candidate.res ) {
365
+ setResolution( candidate, candidate.set.sizes );
366
+ }
367
+ }
368
+ return candidate;
42
369
  }
43
- function getCandidateForSrc(src, set) {
370
+
371
+ function getCandidateForSrc( src, set ) {
44
372
  var i, candidate, candidates;
45
- if (src && set) for (candidates = ri.parseSet(set), src = ri.makeUrl(src), i = 0; i < candidates.length; i++) if (src == ri.makeUrl(candidates[i].url)) {
46
- candidate = candidates[i];
47
- break;
373
+ if ( src && set ) {
374
+ candidates = ri.parseSet( set );
375
+ src = ri.makeUrl(src);
376
+ for ( i = 0; i < candidates.length; i++ ) {
377
+ if ( src == ri.makeUrl(candidates[ i ].url) ) {
378
+ candidate = candidates[ i ];
379
+ break;
380
+ }
381
+ }
48
382
  }
49
383
  return candidate;
50
384
  }
51
- function getAllSourceElements(picture, candidates) {
52
- var i, len, source, srcset, sources = picture.getElementsByTagName("source");
53
- for (i = 0, len = sources.length; len > i; i++) source = sources[i], source[ri.ns] = !0,
54
- srcset = source.getAttribute("srcset"), srcset && candidates.push({
55
- srcset: srcset,
56
- media: source.getAttribute("media"),
57
- type: source.getAttribute("type"),
58
- sizes: source.getAttribute("sizes")
59
- });
385
+
386
+
387
+ function getAllSourceElements( picture, candidates ) {
388
+ var i, len, source, srcset;
389
+
390
+ // SPEC mismatch intended for size and perf:
391
+ // actually only source elements preceding the img should be used
392
+ // also note: don't use qsa here, because IE8 sometimes doesn't like source as the key part in a selector
393
+ var sources = picture.getElementsByTagName( "source" );
394
+
395
+ for ( i = 0, len = sources.length; i < len; i++ ) {
396
+ source = sources[ i ];
397
+ source[ ri.ns ] = true;
398
+ srcset = source.getAttribute( "srcset" );
399
+
400
+ if ( RIDEBUG && document.documentMode != 9 && source.parentNode != picture ) {
401
+ warn( "all source elements have to be a child of the picture element. For IE9 support wrap them in an audio/video element, BUT with conditional comments" );
402
+ }
403
+ // if source does not have a srcset attribute, skip
404
+ if ( srcset ) {
405
+ candidates.push( {
406
+ srcset: srcset,
407
+ media: source.getAttribute( "media" ),
408
+ type: source.getAttribute( "type" ),
409
+ sizes: source.getAttribute( "sizes" )
410
+ } );
411
+ }
412
+ if ( RIDEBUG && source.getAttribute( "src" ) ) {
413
+ warn( "`src` on `source` invalid, use `srcset`." );
414
+ }
415
+ }
416
+
417
+ if ( RIDEBUG ) {
418
+ var srcTest = ri.qsa( picture, "source, img");
419
+ if ( srcTest[ srcTest.length - 1].nodeName.toUpperCase() == "SOURCE" ) {
420
+ warn( "all sources inside picture have to precede the img element" );
421
+ }
422
+ }
60
423
  }
61
- document.createElement("picture");
62
- var lowTreshHold, partialLowTreshHold, isLandscape, lazyFactor, tMemory, substractCurRes, eminpx, alwaysCheckWDescriptor, resizeThrottle, ri = {}, noop = function() {}, image = document.createElement("img"), getImgAttr = image.getAttribute, setImgAttr = image.setAttribute, removeImgAttr = image.removeAttribute, docElem = document.documentElement, types = {}, cfg = {
63
- xQuant: 1,
64
- lazyFactor: .4,
65
- maxX: 2
66
- }, srcAttr = "data-risrc", srcsetAttr = srcAttr + "set", reflowBug = "webkitBackfaceVisibility" in docElem.style, ua = navigator.userAgent, supportNativeLQIP = /AppleWebKit/i.test(ua), supportAbort = /rident/.test(ua) || /ecko/.test(ua) && ua.match(/rv\:(\d+)/) && RegExp.$1 > 35, imgAbortCount = 0, curSrcProp = "currentSrc", regWDesc = /\s+\+?\d+(e\d+)?w/, regSize = /(\([^)]+\))?\s*(.+)/, regDescriptor = /^([\+eE\d\.]+)(w|x)$/, regHDesc = /\s*\d+h\s*/, setOptions = window.respimgCFG, baseStyle = ("https:" == location.protocol,
67
- "position:absolute;left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;overflow:hidden;clip:rect(0px, 0px, 0px, 0px)"), fsCss = "font-size:100%!important;", isVwDirty = !0, cssCache = {}, sizeLengthCache = {}, DPR = window.devicePixelRatio, units = {
68
- px: 1,
69
- "in": 96
70
- }, anchor = document.createElement("a"), alreadyRun = !1, on = function(obj, evt, fn, capture) {
71
- obj.addEventListener ? obj.addEventListener(evt, fn, capture || !1) : obj.attachEvent && obj.attachEvent("on" + evt, fn);
72
- }, off = function(obj, evt, fn, capture) {
73
- obj.removeEventListener ? obj.removeEventListener(evt, fn, capture || !1) : obj.detachEvent && obj.detachEvent("on" + evt, fn);
74
- }, memoize = function(fn) {
75
- var cache = {};
76
- return function(input) {
77
- return input in cache || (cache[input] = fn(input)), cache[input];
78
- };
79
- }, evalCSS = function() {
80
- var regLength = /^([\d\.]+)(em|vw|px)$/, replace = function() {
81
- for (var args = arguments, index = 0, string = args[0]; ++index in args; ) string = string.replace(args[index], args[++index]);
82
- return string;
83
- }, buidlStr = memoize(function(css) {
84
- return "return " + replace((css || "").toLowerCase(), /\band\b/g, "&&", /,/g, "||", /min-([a-z-\s]+):/g, "e.$1>=", /max-([a-z-\s]+):/g, "e.$1<=", /calc([^)]+)/g, "($1)", /(\d+[\.]*[\d]*)([a-z]+)/g, "($1 * e.$2)", /^(?!(e.[a-z]|[0-9\.&=|><\+\-\*\(\)\/])).*/gi, "");
85
- });
86
- return function(css, length) {
87
- var parsedLength;
88
- if (!(css in cssCache)) if (cssCache[css] = !1, length && (parsedLength = css.match(regLength))) cssCache[css] = parsedLength[1] * units[parsedLength[2]]; else try {
89
- cssCache[css] = new Function("e", buidlStr(css))(units);
90
- } catch (e) {}
91
- return cssCache[css];
92
- };
93
- }(), setResolution = function(candidate, sizesattr) {
94
- return candidate.w ? (candidate.cWidth = ri.calcListLength(sizesattr || "100vw"),
95
- candidate.res = candidate.w / candidate.cWidth) : candidate.res = candidate.x, candidate;
96
- }, respimage = function(opt) {
97
- var elements, i, plen, options = opt || {};
98
- if (options.elements && 1 == options.elements.nodeType && ("IMG" == options.elements.nodeName.toUpperCase() ? options.elements = [ options.elements ] : (options.context = options.elements,
99
- options.elements = null)), elements = options.elements || ri.qsa(options.context || document, options.reevaluate || options.reparse ? ri.sel : ri.selShort),
100
- plen = elements.length) {
101
- for (ri.setupRun(options), alreadyRun = !0, i = 0; plen > i; i++) imgAbortCount++,
102
- 6 > imgAbortCount && !elements[i].complete && imgAbortCount++, ri.fillImg(elements[i], options);
103
- ri.teardownRun(options), imgAbortCount++;
104
- }
105
- }, reevaluateAfterLoad = function() {
106
- var onload = function() {
107
- off(this, "load", onload), off(this, "error", onload), ri.fillImgs({
108
- elements: [ this ]
109
- });
110
- };
111
- return function(img) {
112
- off(img, "load", onload), off(img, "error", onload), on(img, "error", onload), on(img, "load", onload);
113
- };
114
- }(), parseDescriptor = memoize(function(descriptor) {
115
- var descriptorObj = [ 1, "x" ], parsedDescriptor = trim(descriptor || "");
116
- return parsedDescriptor && (parsedDescriptor = parsedDescriptor.replace(regHDesc, ""),
117
- descriptorObj = parsedDescriptor.match(regDescriptor) ? [ 1 * RegExp.$1, RegExp.$2 ] : !1),
118
- descriptorObj;
424
+
425
+ // namespace
426
+ ri.ns = ("ri" + new Date().getTime()).substr(0, 9);
427
+
428
+ // srcset support test
429
+ ri.supSrcset = "srcset" in image;
430
+ ri.supSizes = "sizes" in image;
431
+
432
+ // using ri.qsa instead of dom traversing does scale much better,
433
+ // especially on sites mixing responsive and non-responsive images
434
+ ri.selShort = "picture>img,img[srcset]";
435
+ ri.sel = ri.selShort;
436
+ ri.cfg = cfg;
437
+
438
+ if ( ri.supSrcset ) {
439
+ ri.sel += ",img[" + srcsetAttr + "]";
440
+ }
441
+
442
+ /**
443
+ * Shortcut property for `devicePixelRatio` ( for easy overriding in tests )
444
+ */
445
+ ri.DPR = (DPR || 1 );
446
+ ri.u = units;
447
+
448
+ // container of supported mime types that one might need to qualify before using
449
+ ri.types = types;
450
+
451
+ alwaysCheckWDescriptor = ri.supSrcset && !ri.supSizes;
452
+
453
+ ri.setSize = noop;
454
+
455
+ /**
456
+ * Gets a string and returns the absolute URL
457
+ * @param src
458
+ * @returns {String} absolute URL
459
+ */
460
+ ri.makeUrl = memoize(function(src) {
461
+ anchor.href = src;
462
+ return anchor.href;
119
463
  });
120
- curSrcProp in image || (curSrcProp = "src"), types["image/jpeg"] = !0, types["image/gif"] = !0,
121
- types["image/png"] = !0, types["image/svg+xml"] = document.implementation.hasFeature("http://wwwindow.w3.org/TR/SVG11/feature#Image", "1.1"),
122
- ri.ns = ("ri" + new Date().getTime()).substr(0, 9), ri.supSrcset = "srcset" in image,
123
- ri.supSizes = "sizes" in image, ri.selShort = "picture>img,img[srcset]", ri.sel = ri.selShort,
124
- ri.cfg = cfg, ri.supSrcset && (ri.sel += ",img[" + srcsetAttr + "]"), ri.DPR = DPR || 1,
125
- ri.u = units, ri.types = types, alwaysCheckWDescriptor = ri.supSrcset && !ri.supSizes,
126
- ri.setSize = noop, ri.makeUrl = memoize(function(src) {
127
- return anchor.href = src, anchor.href;
128
- }), ri.qsa = function(context, sel) {
464
+
465
+ /**
466
+ * Gets a DOM element or document and a selctor and returns the found matches
467
+ * Can be extended with jQuery/Sizzle for IE7 support
468
+ * @param context
469
+ * @param sel
470
+ * @returns {NodeList}
471
+ */
472
+ ri.qsa = function(context, sel) {
129
473
  return context.querySelectorAll(sel);
130
- }, ri.matchesMedia = function() {
131
- return ri.matchesMedia = window.matchMedia && (matchMedia("(min-width: 0.1em)") || {}).matches ? function(media) {
132
- return !media || matchMedia(media).matches;
133
- } : ri.mMQ, ri.matchesMedia.apply(this, arguments);
134
- }, ri.mMQ = function(media) {
135
- return media ? evalCSS(media) : !0;
136
- }, ri.calcLength = function(sourceSizeValue) {
137
- var value = evalCSS(sourceSizeValue, !0) || !1;
138
- return 0 > value && (value = !1), value;
139
- }, ri.supportsType = function(type) {
140
- return type ? types[type] : !0;
141
- }, ri.parseSize = memoize(function(sourceSizeStr) {
142
- var match = (sourceSizeStr || "").match(regSize);
474
+ };
475
+
476
+ /**
477
+ * Shortcut method for matchMedia ( for easy overriding in tests )
478
+ * wether native or ri.mMQ is used will be decided lazy on first call
479
+ * @returns {boolean}
480
+ */
481
+ ri.matchesMedia = function() {
482
+ if ( window.matchMedia && (matchMedia( "(min-width: 0.1em)" ) || {}).matches ) {
483
+ ri.matchesMedia = function( media ) {
484
+ return !media || ( matchMedia( media ).matches );
485
+ };
486
+ } else {
487
+ ri.matchesMedia = ri.mMQ;
488
+ }
489
+
490
+ return ri.matchesMedia.apply( this, arguments );
491
+ };
492
+
493
+ /**
494
+ * A simplified matchMedia implementation for IE8 and IE9
495
+ * handles only min-width/max-width with px or em values
496
+ * @param media
497
+ * @returns {boolean}
498
+ */
499
+ ri.mMQ = function( media ) {
500
+ return media ? evalCSS(media) : true;
501
+ };
502
+
503
+
504
+ /**
505
+ * Returns the calculated length in css pixel from the given sourceSizeValue
506
+ * http://dev.w3.org/csswg/css-values-3/#length-value
507
+ * intended Spec mismatches:
508
+ * * Does not check for invalid use of CSS functions
509
+ * * Does handle a computed length of 0 the same as a negative and therefore invalid value
510
+ * @param sourceSizeValue
511
+ * @returns {Number}
512
+ */
513
+ ri.calcLength = function( sourceSizeValue ) {
514
+
515
+ var value = evalCSS(sourceSizeValue, true) || false;
516
+ if(value < 0){
517
+ value = false;
518
+ }
519
+
520
+ if ( RIDEBUG && (value === false || value < 0) ) {
521
+ warn( "invalid source size: " + sourceSizeValue );
522
+ }
523
+ return value;
524
+ };
525
+
526
+ /**
527
+ * Takes a type string and checks if its supported
528
+ */
529
+
530
+ ri.supportsType = function( type ) {
531
+ return ( type ) ? types[ type ] : true;
532
+ };
533
+
534
+ /**
535
+ * Parses a sourceSize into mediaCondition (media) and sourceSizeValue (length)
536
+ * @param sourceSizeStr
537
+ * @returns {*}
538
+ */
539
+ ri.parseSize = memoize(function( sourceSizeStr ) {
540
+ var match = ( sourceSizeStr || "" ).match(regSize);
143
541
  return {
144
542
  media: match && match[1],
145
543
  length: match && match[2]
146
544
  };
147
- }), ri.parseSet = function(set) {
148
- if (!set.cands) {
149
- var pos, url, descriptor, last, descpos, can, srcset = set.srcset;
150
- for (set.cands = []; srcset; ) srcset = srcset.replace(/^\s+/g, ""), pos = srcset.search(/\s/g),
151
- descriptor = null, -1 != pos ? (url = srcset.slice(0, pos), last = url.charAt(url.length - 1),
152
- "," != last && url || (url = url.replace(/,+$/, ""), descriptor = ""), srcset = srcset.slice(pos + 1),
153
- null == descriptor && (descpos = srcset.indexOf(","), -1 != descpos ? (descriptor = srcset.slice(0, descpos),
154
- srcset = srcset.slice(descpos + 1)) : (descriptor = srcset, srcset = ""))) : (url = srcset,
155
- srcset = ""), url && (descriptor = parseDescriptor(descriptor)) && (can = {
156
- url: url.replace(/^,+/, ""),
157
- set: set
158
- }, can[descriptor[1]] = descriptor[0], "x" == descriptor[1] && 1 == descriptor[0] && (set.has1x = !0),
159
- set.cands.push(can));
545
+ });
546
+
547
+ ri.parseSet = function( set ) {
548
+ /*
549
+ * A lot of this was pulled from Boris Smus’ parser for the now-defunct WHATWG `srcset`
550
+ * https://github.com/borismus/srcset-polyfill/blob/master/js/srcset-info.js
551
+ *
552
+ * 1. Let input (`srcset`) be the value passed to this algorithm.
553
+ * 2. Let position be a pointer into input, initially pointing at the start of the string.
554
+ * 3. Let raw candidates be an initially empty ordered list of URLs with associated
555
+ * unparsed descriptors. The order of entries in the list is the order in which entries
556
+ * are added to the list.
557
+ */
558
+
559
+ if ( !set.cands ) {
560
+
561
+ var pos, url, descriptor, last, descpos, can, firstDescriptorType;
562
+ var srcset = set.srcset;
563
+
564
+ set.cands = [];
565
+
566
+ while ( srcset ) {
567
+ srcset = srcset.replace(/^\s+/g,"");
568
+ // 5. Collect a sequence of characters that are not space characters, and let that be url.
569
+ pos = srcset.search(/\s/g);
570
+ descriptor = null;
571
+ if ( pos != -1 ) {
572
+ url = srcset.slice( 0, pos );
573
+ last = url.charAt( url.length - 1 );
574
+ // 6. If url ends with a U+002C COMMA character (,), remove that character from url
575
+ // and let descriptors be the empty string. Otherwise, follow these substeps
576
+ // 6.1. If url is empty, then jump to the step labeled descriptor parser.
577
+ if ( last == "," || !url ) {
578
+ url = url.replace(/,+$/, "");
579
+ descriptor = "";
580
+ }
581
+ srcset = srcset.slice( pos + 1 );
582
+ // 6.2. Collect a sequence of characters that are not U+002C COMMA characters (,), and
583
+ // let that be descriptors.
584
+ if ( descriptor == null ) {
585
+ descpos = srcset.indexOf( "," );
586
+ if ( descpos != -1 ) {
587
+ descriptor = srcset.slice( 0, descpos );
588
+ srcset = srcset.slice( descpos + 1 );
589
+ } else {
590
+ descriptor = srcset;
591
+ srcset = "";
592
+ }
593
+ }
594
+ } else {
595
+ url = srcset;
596
+ srcset = "";
597
+ }
598
+
599
+ // 7. Add url to raw candidates, associated with descriptors.
600
+ if ( url && (descriptor = parseDescriptor( descriptor )) ) {
601
+
602
+ if ( RIDEBUG ) {
603
+ if ( !firstDescriptorType ) {
604
+ firstDescriptorType = set.sizes ? "w" : descriptor[1];
605
+ }
606
+ if ( firstDescriptorType != descriptor[1] ) {
607
+ warn("mixing x with a w descriptor/sizes attribute in one srcset doesn't make sense in most cases and is invalid.");
608
+ }
609
+ }
610
+ can = {
611
+ url: url.replace(/^,+/, ""),
612
+ set: set
613
+ };
614
+ can[descriptor[1]] = descriptor[0];
615
+
616
+ if(descriptor[1] == 'x' && descriptor[0] == 1){
617
+ set.has1x = true;
618
+ }
619
+
620
+ set.cands.push(can);
621
+ }
622
+ }
623
+ }
624
+
625
+ return set.cands;
626
+ };
627
+
628
+ /**
629
+ * returns 1em in css px for html/body default size
630
+ * function taken from respondjs
631
+ * @returns {*|number}
632
+ */
633
+ ri.getEmValue = function() {
634
+ var body;
635
+ if ( !eminpx && (body = document.body) ) {
636
+ var div = document.createElement( "div" ),
637
+ originalHTMLCSS = docElem.style.cssText,
638
+ originalBodyCSS = body.style.cssText;
639
+
640
+ div.style.cssText = baseStyle;
641
+
642
+ // 1em in a media query is the value of the default font size of the browser
643
+ // reset docElem and body to ensure the correct value is returned
644
+ docElem.style.cssText = fsCss;
645
+ body.style.cssText = fsCss;
646
+
647
+ body.appendChild( div );
648
+ eminpx = div.offsetWidth;
649
+ body.removeChild( div );
650
+
651
+ //also update eminpx before returning
652
+ eminpx = parseFloat( eminpx, 10 );
653
+
654
+ // restore the original values
655
+ docElem.style.cssText = originalHTMLCSS;
656
+ body.style.cssText = originalBodyCSS;
657
+
658
+ }
659
+ return eminpx || 16;
660
+ };
661
+
662
+
663
+ /**
664
+ * Takes a string of sizes and returns the width in pixels as a number
665
+ */
666
+ ri.calcListLength = function( sourceSizeListStr ) {
667
+ // Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33%
668
+ //
669
+ // or (min-width:30em) calc(30% - 15px)
670
+ if ( !(sourceSizeListStr in sizeLengthCache) || cfg.uT ) {
671
+ var sourceSize, parsedSize, length, media, i, len;
672
+ var sourceSizeList = trim( sourceSizeListStr ).split( /\s*,\s*/ );
673
+ var winningLength = false;
674
+ for ( i = 0, len = sourceSizeList.length; i < len; i++ ) {
675
+ // Match <media-condition>? length, ie ( min-width: 50em ) 100%
676
+ sourceSize = sourceSizeList[ i ];
677
+ // Split "( min-width: 50em ) 100%" into separate strings
678
+ parsedSize = ri.parseSize( sourceSize );
679
+ length = parsedSize.length;
680
+ media = parsedSize.media;
681
+
682
+ if ( !length ) {
683
+ continue;
684
+ }
685
+ // if there is no media query or it matches, choose this as our winning length
686
+ // and end algorithm
687
+ if ( ri.matchesMedia( media ) && (winningLength = ri.calcLength( length )) !== false ) {
688
+ break;
689
+ }
690
+ }
691
+ // pass the length to a method that can properly determine length
692
+ // in pixels based on these formats: http://dev.w3.org/csswg/css-values-3/#length-value
693
+ sizeLengthCache[ sourceSizeListStr ] = !winningLength ? units.width : winningLength;
694
+ }
695
+
696
+ return sizeLengthCache[ sourceSizeListStr ];
697
+ };
698
+
699
+ /**
700
+ * Takes a candidate object with a srcset property in the form of url/
701
+ * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or
702
+ * "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or
703
+ * "images/pic-small.png"
704
+ * Get an array of image candidates in the form of
705
+ * {url: "/foo/bar.png", resolution: 1}
706
+ * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value
707
+ * If sizes is specified, res is calculated
708
+ */
709
+ ri.setRes = function( set ) {
710
+ var candidates;
711
+ if ( set ) {
712
+
713
+ candidates = ri.parseSet( set );
714
+
715
+ for ( var i = 0, len = candidates.length; i < len; i++ ) {
716
+ setResolution( candidates[ i ], set.sizes );
717
+ }
718
+ }
719
+ return candidates;
720
+ };
721
+
722
+ ri.setRes.res = setResolution;
723
+
724
+ ri.applySetCandidate = function( candidates, img ) {
725
+ if ( !candidates.length ) {return;}
726
+ var candidate,
727
+ dpr,
728
+ i,
729
+ j,
730
+ diff,
731
+ length,
732
+ bestCandidate,
733
+ curSrc,
734
+ curCan,
735
+ isSameSet,
736
+ candidateSrc,
737
+ abortCurSrc,
738
+ oldRes;
739
+
740
+ var imageData = img[ ri.ns ];
741
+ var evaled = evalID;
742
+ var lazyF = lazyFactor;
743
+ var sub = substractCurRes;
744
+
745
+ curSrc = imageData.curSrc || img[curSrcProp];
746
+
747
+ curCan = imageData.curCan || setSrcToCur(img, curSrc, candidates[0].set);
748
+
749
+ dpr = ri.DPR;
750
+
751
+ oldRes = curCan && curCan.res;
752
+
753
+ //if we have a current source, we might either become lazy or give this source some advantage
754
+ if ( !bestCandidate && curSrc ) {
755
+
756
+ abortCurSrc = (supportAbort && !img.complete && curCan && oldRes - 0.2 > dpr);
757
+
758
+ if( !abortCurSrc && (!curCan || tMemory > oldRes) ){
759
+
760
+ //add some lazy padding to the src
761
+ if ( curCan && oldRes < dpr && oldRes > lowTreshHold ) {
762
+
763
+
764
+ if(oldRes < partialLowTreshHold){
765
+ lazyF *= 0.8;
766
+ sub += (0.04 * dpr);
767
+ }
768
+
769
+ curCan.res += lazyF * Math.pow(oldRes - sub, 2);
770
+ }
771
+
772
+ isSameSet = !imageData.pic || (curCan && curCan.set == candidates[ 0 ].set);
773
+
774
+ if ( curCan && isSameSet && curCan.res >= dpr ) {
775
+ bestCandidate = curCan;
776
+ }
777
+ }
778
+ }
779
+
780
+ if ( !bestCandidate ) {
781
+ if ( oldRes ) {
782
+ curCan.res = curCan.res - ((curCan.res - oldRes) / 2);
783
+ }
784
+
785
+ candidates.sort( ascendingSort );
786
+
787
+ length = candidates.length;
788
+ bestCandidate = candidates[ length - 1 ];
789
+
790
+ for ( i = 0; i < length; i++ ) {
791
+ candidate = candidates[ i ];
792
+ if ( candidate.res >= dpr ) {
793
+ j = i - 1;
794
+
795
+ // we have found the perfect candidate,
796
+ // but let's improve this a little bit with some assumptions ;-)
797
+ if (candidates[ j ] &&
798
+ (diff = (candidate.res - dpr)) &&
799
+ (abortCurSrc || curSrc != ri.makeUrl( candidate.url )) &&
800
+ chooseLowRes(candidates[ j ].res, diff, dpr)) {
801
+ bestCandidate = candidates[ j ];
802
+
803
+ } else {
804
+ bestCandidate = candidate;
805
+ }
806
+ break;
807
+ }
808
+ }
809
+ }
810
+
811
+ if ( oldRes ) {
812
+ curCan.res = oldRes;
813
+ }
814
+
815
+ if ( bestCandidate ) {
816
+
817
+ candidateSrc = ri.makeUrl( bestCandidate.url );
818
+
819
+
820
+ imageData.curSrc = candidateSrc;
821
+ imageData.curCan = bestCandidate;
822
+
823
+ if ( candidateSrc != curSrc ) {
824
+ ri.setSrc( img, bestCandidate );
825
+ if ( RIDEBUG ) {
826
+ testImgDimensions(img, bestCandidate);
827
+ if(isSSL && !bestCandidate.url.indexOf( "http:" )){
828
+ warn( "insecure: " + candidateSrc );
829
+ }
830
+ }
831
+ }
832
+ ri.setSize( img );
833
+ }
834
+
835
+ return evaled;
836
+ };
837
+
838
+ ri.setSrc = function( img, bestCandidate ) {
839
+ var origStyle;
840
+ img.src = bestCandidate.url;
841
+
842
+
843
+ if ( reflowBug ) {
844
+ origStyle = img.style.zoom;
845
+ img.style.zoom = "0.999";
846
+
847
+ // next line only should trigger a repaint
848
+ // if... is only done to trick dead code removal
849
+ if ( img.offsetWidth || 1 ) {
850
+ img.style.zoom = origStyle;
851
+ }
852
+ }
853
+ };
854
+
855
+ ri.getSet = function( img ) {
856
+ var i, set, supportsType;
857
+ var match = false;
858
+ var sets = img [ ri.ns ].sets;
859
+
860
+ for ( i = 0; i < sets.length && !match; i++ ) {
861
+ set = sets[i];
862
+
863
+ if ( !set.srcset || !ri.matchesMedia( set.media ) || !(supportsType = ri.supportsType( set.type )) ) {
864
+ continue;
865
+ }
866
+
867
+ if ( supportsType == "pending" ) {
868
+ set = supportsType;
869
+ }
870
+
871
+ match = set;
872
+ break;
873
+ }
874
+
875
+ return match;
876
+ };
877
+
878
+ ri.parseSets = function( element, parent, options ) {
879
+ var srcsetAttribute, imageSet, isWDescripor, srcsetParsed;
880
+
881
+ var hasPicture = parent.nodeName.toUpperCase() == "PICTURE";
882
+ var imageData = element[ ri.ns ];
883
+
884
+ if ( imageData.src === undefined || options.src ) {
885
+ imageData.src = getImgAttr.call( element, "src" );
886
+ if ( imageData.src ) {
887
+ setImgAttr.call( element, srcAttr, imageData.src );
888
+ } else {
889
+ removeImgAttr.call( element, srcAttr );
890
+ }
891
+ }
892
+
893
+ if ( imageData.srcset === undefined || !ri.supSrcset || element.srcset || options.srcset ) {
894
+ srcsetAttribute = getImgAttr.call( element, "srcset" );
895
+ imageData.srcset = srcsetAttribute;
896
+ srcsetParsed = true;
160
897
  }
161
- return set.cands;
162
- }, ri.getEmValue = function() {
163
- var body;
164
- if (!eminpx && (body = document.body)) {
165
- var div = document.createElement("div"), originalHTMLCSS = docElem.style.cssText, originalBodyCSS = body.style.cssText;
166
- div.style.cssText = baseStyle, docElem.style.cssText = fsCss, body.style.cssText = fsCss,
167
- body.appendChild(div), eminpx = div.offsetWidth, body.removeChild(div), eminpx = parseFloat(eminpx, 10),
168
- docElem.style.cssText = originalHTMLCSS, body.style.cssText = originalBodyCSS;
898
+
899
+ imageData.sets = [];
900
+
901
+ if ( hasPicture ) {
902
+ imageData.pic = true;
903
+ getAllSourceElements( parent, imageData.sets );
169
904
  }
170
- return eminpx || 16;
171
- }, ri.calcListLength = function(sourceSizeListStr) {
172
- if (!(sourceSizeListStr in sizeLengthCache) || cfg.uT) {
173
- var sourceSize, parsedSize, length, media, i, len, sourceSizeList = trim(sourceSizeListStr).split(/\s*,\s*/), winningLength = !1;
174
- for (i = 0, len = sourceSizeList.length; len > i && (sourceSize = sourceSizeList[i],
175
- parsedSize = ri.parseSize(sourceSize), length = parsedSize.length, media = parsedSize.media,
176
- !length || !ri.matchesMedia(media) || (winningLength = ri.calcLength(length)) === !1); i++) ;
177
- sizeLengthCache[sourceSizeListStr] = winningLength ? winningLength : units.width;
178
- }
179
- return sizeLengthCache[sourceSizeListStr];
180
- }, ri.setRes = function(set) {
181
- var candidates;
182
- if (set) {
183
- candidates = ri.parseSet(set);
184
- for (var i = 0, len = candidates.length; len > i; i++) setResolution(candidates[i], set.sizes);
905
+
906
+ if ( imageData.srcset ) {
907
+ imageSet = {
908
+ srcset: imageData.srcset,
909
+ sizes: getImgAttr.call( element, "sizes" )
910
+ };
911
+
912
+ imageData.sets.push( imageSet );
913
+
914
+ isWDescripor = (alwaysCheckWDescriptor || imageData.src) && regWDesc.test(imageData.srcset || '');
915
+
916
+ // add normal src as candidate, if source has no w descriptor
917
+ if ( !isWDescripor && imageData.src && !getCandidateForSrc(imageData.src, imageSet) && !imageSet.has1x ) {
918
+ imageSet.srcset += ", " + imageData.src;
919
+ imageSet.cands.push({
920
+ url: imageData.src,
921
+ x: 1,
922
+ set: imageSet
923
+ });
924
+ }
925
+
926
+ if ( RIDEBUG && !hasPicture && isWDescripor && imageData.src && imageSet.srcset.indexOf(element[ ri.ns ].src) == -1 ) {
927
+ warn("The fallback candidate (`src`) isn't described inside the srcset attribute. Normally you want to describe all available candidates.");
928
+ }
929
+
930
+ } else if ( imageData.src ) {
931
+ imageData.sets.push( {
932
+ srcset: imageData.src,
933
+ sizes: null
934
+ } );
185
935
  }
186
- return candidates;
187
- }, ri.setRes.res = setResolution, ri.applySetCandidate = function(candidates, img) {
188
- if (candidates.length) {
189
- var candidate, dpr, i, j, diff, length, bestCandidate, curSrc, curCan, isSameSet, candidateSrc, abortCurSrc, oldRes, imageData = img[ri.ns], evaled = !0, lazyF = lazyFactor, sub = substractCurRes;
190
- if (curSrc = imageData.curSrc || img[curSrcProp], curCan = imageData.curCan || setSrcToCur(img, curSrc, candidates[0].set),
191
- dpr = ri.DPR, oldRes = curCan && curCan.res, !bestCandidate && curSrc && (abortCurSrc = supportAbort && !img.complete && curCan && oldRes > dpr,
192
- abortCurSrc || curCan && !(tMemory > oldRes) || (curCan && dpr > oldRes && oldRes > lowTreshHold && (partialLowTreshHold > oldRes && (lazyF *= .87,
193
- sub += .04 * dpr), curCan.res += lazyF * Math.pow(oldRes - sub, 2)), isSameSet = !imageData.pic || curCan && curCan.set == candidates[0].set,
194
- curCan && isSameSet && curCan.res >= dpr ? bestCandidate = curCan : supportNativeLQIP || img.complete || !getImgAttr.call(img, "src") || img.lazyload || supportAbort && !(5 > imgAbortCount) || !isSameSet && inView(img) || (bestCandidate = curCan,
195
- candidateSrc = curSrc, evaled = "L", reevaluateAfterLoad(img)))), !bestCandidate) for (oldRes && (curCan.res = curCan.res - (curCan.res - oldRes) / 2),
196
- candidates.sort(ascendingSort), length = candidates.length, bestCandidate = candidates[length - 1],
197
- i = 0; length > i; i++) if (candidate = candidates[i], candidate.res >= dpr) {
198
- j = i - 1, bestCandidate = candidates[j] && (diff = candidate.res - dpr) && (abortCurSrc || curSrc != ri.makeUrl(candidate.url)) && chooseLowRes(candidates[j].res, diff, dpr) ? candidates[j] : candidate;
199
- break;
200
- }
201
- return oldRes && (curCan.res = oldRes), bestCandidate && (candidateSrc = ri.makeUrl(bestCandidate.url),
202
- imageData.curSrc = candidateSrc, imageData.curCan = bestCandidate, candidateSrc != curSrc && ri.setSrc(img, bestCandidate),
203
- ri.setSize(img)), evaled;
204
- }
205
- }, ri.setSrc = function(img, bestCandidate) {
206
- var origStyle;
207
- img.src = bestCandidate.url, reflowBug && (origStyle = img.style.zoom, img.style.zoom = "0.999",
208
- img.style.zoom = origStyle);
209
- }, ri.getSet = function(img) {
210
- var i, set, supportsType, match = !1, sets = img[ri.ns].sets;
211
- for (i = 0; i < sets.length && !match; i++) if (set = sets[i], set.srcset && ri.matchesMedia(set.media) && (supportsType = ri.supportsType(set.type))) {
212
- "pending" == supportsType && (set = supportsType), match = set;
213
- break;
936
+
937
+ imageData.curCan = null;
938
+ imageData.curSrc = undefined;
939
+
940
+ // if img has picture or the srcset was removed or has a srcset and does not support srcset at all
941
+ // or has a w descriptor (and does not support sizes) set support to false to evaluate
942
+ imageData.supported = !( hasPicture || ( imageSet && !ri.supSrcset ) || isWDescripor );
943
+
944
+ if ( srcsetParsed && ri.supSrcset && !imageData.supported ) {
945
+ if ( srcsetAttribute ) {
946
+ setImgAttr.call( element, srcsetAttr, srcsetAttribute );
947
+ element.srcset = "";
948
+ } else {
949
+ removeImgAttr.call( element, srcsetAttr );
950
+ }
214
951
  }
215
- return match;
216
- }, ri.parseSets = function(element, parent) {
217
- var srcsetAttribute, imageSet, isWDescripor, srcsetParsed, hasPicture = "PICTURE" == parent.nodeName.toUpperCase(), imageData = element[ri.ns];
218
- imageData.src === undefined && (imageData.src = getImgAttr.call(element, "src"),
219
- imageData.src ? setImgAttr.call(element, srcAttr, imageData.src) : removeImgAttr.call(element, srcAttr)),
220
- imageData.srcset === undefined && (srcsetAttribute = getImgAttr.call(element, "srcset"),
221
- imageData.srcset = srcsetAttribute, srcsetParsed = !0), imageData.sets = [], hasPicture && (imageData.pic = !0,
222
- getAllSourceElements(parent, imageData.sets)), imageData.srcset ? (imageSet = {
223
- srcset: imageData.srcset,
224
- sizes: getImgAttr.call(element, "sizes")
225
- }, imageData.sets.push(imageSet), isWDescripor = (alwaysCheckWDescriptor || imageData.src) && regWDesc.test(imageData.srcset || ""),
226
- isWDescripor || !imageData.src || getCandidateForSrc(imageData.src, imageSet) || imageSet.has1x || (imageSet.srcset += ", " + imageData.src,
227
- imageSet.cands.push({
228
- url: imageData.src,
229
- x: 1,
230
- set: imageSet
231
- }))) : imageData.src && imageData.sets.push({
232
- srcset: imageData.src,
233
- sizes: null
234
- }), imageData.curCan = null, imageData.supported = !(hasPicture || imageSet && !ri.supSrcset || isWDescripor),
235
- srcsetParsed && ri.supSrcset && !imageData.supported && (srcsetAttribute ? (setImgAttr.call(element, srcsetAttr, srcsetAttribute),
236
- element.srcset = "") : removeImgAttr.call(element, srcsetAttr)), imageData.supported && !imageData.srcset && (!imageData.src && element.src || element.src != ri.makeUrl(imageData.src)) && (null == imageData.src ? element.removeAttribute("src") : element.src = imageData.src),
237
- imageData.parsed = !0;
238
- }, ri.fillImg = function(element, options) {
239
- var parent, imageData, extreme = options.reparse || options.reevaluate;
240
- if (element[ri.ns] || (element[ri.ns] = {}), imageData = element[ri.ns], "L" == imageData.evaled && element.complete && (imageData.evaled = !1),
241
- extreme || !imageData.evaled) {
242
- if (!imageData.parsed || options.reparse) {
243
- if (parent = element.parentNode, !parent) return;
244
- ri.parseSets(element, parent, options);
245
- }
246
- imageData.supported ? imageData.evaled = !0 : applyBestCandidate(element);
247
- }
248
- }, ri.setupRun = function(options) {
249
- (!alreadyRun || options.reevaluate || isVwDirty) && (updateMetrics(), options.elements || options.context || clearTimeout(resizeThrottle));
250
- }, window.HTMLPictureElement ? (respimage = noop, ri.fillImg = noop) : !function() {
251
- var isDomReady, regReady = window.attachEvent ? /d$|^c/ : /d$|^c|^i/, run = function() {
252
- var readyState = document.readyState || "";
253
- timerId = setTimeout(run, "loading" == readyState ? 200 : 999), document.body && (isDomReady = isDomReady || regReady.test(readyState),
254
- ri.fillImgs(), isDomReady && (imgAbortCount += 6, clearTimeout(timerId)));
255
- }, resizeEval = function() {
256
- ri.fillImgs({
257
- reevaluate: !0
258
- });
259
- }, onResize = function() {
260
- clearTimeout(resizeThrottle), isVwDirty = !0, resizeThrottle = setTimeout(resizeEval, 99);
261
- }, timerId = setTimeout(run, document.body ? 9 : 99);
262
- on(window, "resize", onResize), on(document, "readystatechange", run);
263
- }(), ri.respimage = respimage, ri.fillImgs = respimage, ri.teardownRun = noop, respimage._ = ri,
264
- window.respimage = respimage, window.respimgCFG = {
265
- ri: ri,
266
- push: function(args) {
267
- var name = args.shift();
268
- "function" == typeof ri[name] ? ri[name].apply(ri, args) : (cfg[name] = args[0],
269
- alreadyRun && ri.fillImgs({
270
- reevaluate: !0
271
- }));
952
+
953
+ if(imageData.supported && !imageData.srcset && ((!imageData.src && element.src) || element.src != ri.makeUrl(imageData.src))){
954
+ if(imageData.src == null){
955
+ element.removeAttribute('src');
956
+ } else {
957
+ element.src = imageData.src;
958
+ }
272
959
  }
960
+
961
+ if ( RIDEBUG ) {
962
+ testMediaOrder(imageData.sets, 'source');
963
+ }
964
+ imageData.parsed = true;
273
965
  };
274
- for (;setOptions && setOptions.length; ) window.respimgCFG.push(setOptions.shift());
275
- }(window, document);
276
- (function( factory ) {
277
- "use strict";
278
- var interValId;
279
- var intervalIndex = 0;
280
- var run = function(){
281
- if ( window.respimage ) {
282
- factory( window.respimage );
966
+
967
+
968
+ ri.fillImg = function(element, options) {
969
+ var parent, imageData;
970
+ var extreme = options.reselect || options.reevaluate;
971
+
972
+ // expando for caching data on the img
973
+ if ( !element[ ri.ns ] ) {
974
+ element[ ri.ns ] = {};
283
975
  }
284
- if(window.respimage || intervalIndex > 9999){
285
- clearInterval(interValId);
976
+
977
+ imageData = element[ ri.ns ];
978
+
979
+ // if the element has already been evaluated, skip it
980
+ // unless `options.reevaluate` is set to true ( this, for example,
981
+ // is set to true when running `respimage` on `resize` ).
982
+ if ( !extreme && imageData.evaled == evalID ) {
983
+ return;
984
+ }
985
+
986
+ if ( !imageData.parsed || options.reevaluate ) {
987
+ parent = element.parentNode;
988
+ if ( !parent ) {
989
+ return;
990
+ }
991
+ ri.parseSets( element, parent, options );
992
+ }
993
+
994
+ if ( !imageData.supported ) {
995
+ applyBestCandidate( element );
996
+ } else {
997
+ imageData.evaled = evalID;
286
998
  }
287
- intervalIndex++;
288
999
  };
289
- interValId = setInterval(run, 8);
290
1000
 
291
- run();
1001
+ ri.setupRun = function( options ) {
1002
+ if ( !alreadyRun || isVwDirty || DPR != window.devicePixelRatio ) {
1003
+ updateMetrics();
292
1004
 
293
- }( function( respimage ) {
294
- "use strict";
1005
+ // if all images are reevaluated clear the resizetimer
1006
+ if ( !options.elements && !options.context ) {
1007
+ clearTimeout( resizeThrottle );
1008
+ }
1009
+ }
1010
+ };
295
1011
 
296
- var ri = respimage._;
297
- var runningTests = 0;
298
- var setTypeValue = function(types, value){
299
- var i;
300
- for(i = 0; i < types.length; i++){
301
- ri.types[types[i]] = value;
1012
+ // If picture is supported, well, that's awesome.
1013
+ if ( window.HTMLPictureElement ) {
1014
+ respimage = noop;
1015
+ ri.fillImg = noop;
1016
+ } else {
1017
+ // HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround)
1018
+ document.createElement( "picture" );
1019
+
1020
+ /**
1021
+ * Sets up picture polyfill by polling the document
1022
+ * Also attaches respimage on resize and readystatechange
1023
+ */
1024
+ (function() {
1025
+ var isDomReady;
1026
+ var regReady = window.attachEvent ? /d$|^c/ : /d$|^c|^i/;
1027
+ var run = function() {
1028
+ var readyState = document.readyState || "";
1029
+
1030
+ timerId = setTimeout(run, readyState == "loading" ? 200 : 999);
1031
+ if ( document.body ) {
1032
+ isDomReady = isDomReady || regReady.test( readyState );
1033
+ ri.fillImgs();
1034
+ if ( isDomReady ) {
1035
+ clearTimeout( timerId );
1036
+ }
1037
+ }
1038
+ };
1039
+
1040
+ var resizeEval = function() {
1041
+ ri.fillImgs();
1042
+ };
1043
+
1044
+ var onResize = function() {
1045
+ clearTimeout( resizeThrottle );
1046
+ isVwDirty = true;
1047
+ resizeThrottle = setTimeout( resizeEval, 99 );
1048
+ };
1049
+
1050
+ var timerId = setTimeout(run, document.body ? 0 : 20);
1051
+
1052
+ on( window, "resize", onResize );
1053
+ on( document, "readystatechange", run );
1054
+
1055
+ })();
1056
+ }
1057
+
1058
+ ri.respimage = respimage;
1059
+ //use this internally for easy monkey patching/performance testing
1060
+ ri.fillImgs = respimage;
1061
+ ri.teardownRun = noop;
1062
+
1063
+ /* expose methods for testing */
1064
+ respimage._ = ri;
1065
+
1066
+ /* expose respimage */
1067
+ window.respimage = respimage;
1068
+
1069
+ window.respimgCFG = {
1070
+ ri: ri,
1071
+ push: function(args){
1072
+ var name = args.shift();
1073
+ if(typeof ri[name] == "function"){
1074
+ ri[name].apply(ri, args);
1075
+ } else {
1076
+ cfg[name] = args[0];
1077
+ if(alreadyRun){
1078
+ ri.fillImgs({reselect: true});
1079
+ }
1080
+ }
302
1081
  }
303
1082
  };
304
1083
 
305
- if(window.HTMLPictureElement && !ri.cfg.uT){
306
- respimage.testTypeSupport = function(){};
307
- return;
1084
+ while(setOptions && setOptions.length){
1085
+ window.respimgCFG.push(setOptions.shift());
308
1086
  }
309
1087
 
310
- ri.types["image/bmp"] = true;
311
- ri.types["image/x-bmp"] = true;
1088
+ if ( RIDEBUG ) {
1089
+ warn( "Responsive image debugger active. Do not use in production, because it slows things down! extremly" );
312
1090
 
313
- respimage.testTypeSupport = function(types, url, width, useCanvas){
314
- if(typeof types == "string"){
315
- types = types.split(/\s*\,*\s+/g);
1091
+ if(!document.querySelector || (document.documentMode || 9) < 8){
1092
+ warn("querySelector is needed. IE8 needs to be in strict, standard or edge mode: http://bit.ly/1yGgYU0 or try the ri.oldie.js plugin.");
1093
+ }
1094
+ if( (document.getElementsByTagName("picture")[0] ||{} ).outerHTML == "<PICTURE>" ){
1095
+ warn("IE8 needs to picture shived. Either include respimage.js in <head> or use html5shiv.");
316
1096
  }
317
- var canvas;
318
- var supports = "pending";
319
- var img = document.createElement('img');
320
- var onComplete = function(){
321
- runningTests--;
322
- setTypeValue(types, supports);
323
- if(runningTests < 1){
324
- respimage({reevaluate: true});
325
- }
326
- };
327
1097
 
328
- if(useCanvas){
329
- canvas = document.createElement('canvas');
330
- if(!canvas.getContext){
331
- setTypeValue(types, false);
332
- return;
333
- }
1098
+ if(document.compatMode == "BackCompat"){
1099
+ warn("Browser is in quirksmode. Please make sure to be in strict mode.");
334
1100
  }
335
1101
 
336
- img.onload = function(){
337
- var ctx;
338
- supports = true;
339
- if(width){
340
- supports = img.width == width;
341
- }
1102
+ var testImgDimensions = function (img, candidate) {
1103
+ var onload = function () {
1104
+ var dif, xtreshhold;
1105
+ var imgWidth = img.offsetWidth;
1106
+ var naturalWidth = img.naturalWidth;
1107
+ var canWidth = candidate.cWidth;
1108
+ var res = ri.DPR * cfg.xQuant;
1109
+ var hTresh = 0.84;
1110
+ var lTresh = res > 1 ? 0.5 : 0.75;
342
1111
 
343
- if(useCanvas){
344
- ctx = canvas.getContext('2d');
345
- ctx.drawImage(img, 0, 0);
346
- supports = ctx.getImageData(0, 0, 1, 1).data[3] === 0;
347
- }
348
- onComplete();
349
- };
350
1112
 
351
- img.onerror = function(){
352
- supports = false;
353
- onComplete();
1113
+ if(!canWidth && naturalWidth && candidate.x){
1114
+ canWidth = naturalWidth / res;
1115
+ }
1116
+
1117
+ if (imgWidth && canWidth) {
1118
+ if (imgWidth > canWidth) {
1119
+ dif = canWidth / imgWidth;
1120
+ xtreshhold = lTresh;
1121
+ } else {
1122
+ dif = imgWidth / canWidth;
1123
+ xtreshhold = hTresh;
1124
+ }
1125
+
1126
+ if(Math.abs(imgWidth - canWidth) > 50){
1127
+ if (candidate.w && dif < 0.86) {
1128
+ warn("Check your sizes attribute: " + candidate.set.sizes + " was calculated to: " + canWidth + "px. But your image is shown with a size of " + imgWidth + "px. img: "+ candidate.url);
1129
+ } else if(candidate.x && dif < xtreshhold){
1130
+ //warn("Image too much resized. Image was shown with "+ imgWidth +" but has a normalized width of "+ canWidth +". Maybe you should use a w descriptor instead of an x descriptor. img: "+ candidate.url);
1131
+ }
1132
+ }
1133
+ }
1134
+
1135
+ off(img, "load", onload);
1136
+ };
1137
+
1138
+ on(img, "load", onload);
354
1139
  };
355
- runningTests++;
356
- setTypeValue(types, "pending");
357
- img.src = url;
358
- };
1140
+ var testMediaOrder = (function(){
1141
+ var regex = {
1142
+ minw: /^\s*\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)\s*$/,
1143
+ maxw: /^\s*\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)\s*$/
1144
+ };
359
1145
 
1146
+ var checkSetOrder = function(set, sets, index, type){
1147
+ var i, curSet;
1148
+ for(i = 0; i < index && i < sets.length; i++){
1149
+ curSet = sets[i];
1150
+ if((set._min && curSet._min && set._min >= curSet._min) || (set._max && curSet._max && set._max <= curSet._max)){
1151
+ if(type == 'source'){
1152
+ warn("Order of your source elements matters. Defining "+ set.media + " after "+ curSet.media +" doesn't make sense.");
1153
+ } else {
1154
+ warn("Order inside your sizes attribute does matter. Defining "+ set.media + " after "+ curSet.media +" doesn't make sense.");
1155
+ }
1156
+ }
1157
+ }
1158
+ };
1159
+ var mediaTest = function(sets, type){
1160
+ var i, len, set, lastSet;
360
1161
 
361
- respimage.testTypeSupport("image/webp", "data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==", 1);
362
- respimage.testTypeSupport("image/jp2 image/jpx image/jpm", "data:image/jp2;base64,/0//UQAyAAAAAAABAAAAAgAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAEBwEBBwEBBwEBBwEB/1IADAAAAAEAAAQEAAH/XAAEQED/ZAAlAAFDcmVhdGVkIGJ5IE9wZW5KUEVHIHZlcnNpb24gMi4wLjD/kAAKAAAAAABYAAH/UwAJAQAABAQAAf9dAAUBQED/UwAJAgAABAQAAf9dAAUCQED/UwAJAwAABAQAAf9dAAUDQED/k8+kEAGvz6QQAa/PpBABr994EAk//9k=", 1);
363
- respimage.testTypeSupport("image/vnd.ms-photo", "data:image/vnd.ms-photo;base64,SUm8AQgAAAAFAAG8AQAQAAAASgAAAIC8BAABAAAAAQAAAIG8BAABAAAAAQAAAMC8BAABAAAAWgAAAMG8BAABAAAAHwAAAAAAAAAkw91vA07+S7GFPXd2jckNV01QSE9UTwAZAYBxAAAAABP/gAAEb/8AAQAAAQAAAA==", 1);
364
- respimage.testTypeSupport("video/png video/apng video/x-mng video/x-png", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==", false, true);
1162
+ lastSet = sets[sets.length - 1];
1163
+ if(lastSet && (lastSet.media || lastSet.type)){
1164
+ if(type == 'source'){
1165
+ warn("The last src/srcset shouldn't have any type or media conditions. Use img[src] or img[srcset].");
1166
+ } else {
1167
+ warn("Last sizes attribute shouldn't have any condition otherwise 100vw is used.");
1168
+ }
1169
+ }
1170
+ for(i = 0, len = sets.length; i < len; i++){
1171
+ set = sets[i];
1172
+ if(!set.media || set.type){
1173
+ if(!set.type && i != len - 1){
1174
+ if(type == 'source'){
1175
+ warn("A source element without [media] and [type] doesn't make any sense. Last srcset can be used at the img element. Order is important!");
1176
+ } else {
1177
+ warn("The order of your sizes attribute does matter! The sizes length without a media condition has to be defined as last entry.");
1178
+ }
1179
+ }
1180
+ continue;
1181
+ }
1182
+ set._min = set.media.match( regex.minw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" );
1183
+ set._max = set.media.match( regex.maxw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" );
365
1184
 
366
- }));
1185
+
1186
+ if ( set._min ) {
1187
+ set._min = parseFloat( set._min, 10 ) * (set._min.indexOf( "em" ) > 0 ? ri.getEmValue() : 1);
1188
+ }
1189
+
1190
+ if ( set._max ) {
1191
+ set._max = parseFloat( set._max, 10 ) * (set._max.indexOf( "em" ) > 0 ? ri.getEmValue() : 1);
1192
+ }
1193
+ if(set._min || set._max){
1194
+ checkSetOrder(set, sets, i, type);
1195
+ }
1196
+ }
1197
+ };
1198
+
1199
+ return function(sets){
1200
+ var i, len, sizes, j, sizesSet;
1201
+
1202
+ mediaTest(sets, 'source');
1203
+
1204
+ for(i = 0, len = sets.length; i < len; i++){
1205
+ sizes = trim(sets[i].sizes || '');
1206
+ if(sizes){
1207
+ sizesSet = [];
1208
+ sizes = sizes.split( /\s*,\s*/ );
1209
+ for(j = 0; j < sizes.length; j++){
1210
+ if(sizes[j]){
1211
+ sizesSet.push(ri.parseSize( sizes[j] ));
1212
+ }
1213
+ }
1214
+
1215
+ if(sizesSet.length){
1216
+ mediaTest(sizesSet, 'sizes');
1217
+ }
1218
+ }
1219
+ }
1220
+ };
1221
+ })();
1222
+ }
1223
+
1224
+ } )( window, document );
367
1225
 
368
1226
  (function( factory ) {
369
1227
  "use strict";
@@ -385,10 +1243,10 @@
385
1243
  }( function( respimage, undefined ) {
386
1244
  "use strict";
387
1245
 
1246
+ var document = window.document;
388
1247
  var ri = respimage._;
389
1248
  var knownWidths = {};
390
1249
  var cfg = ri.cfg;
391
- var curSrcProp = "currentSrc";
392
1250
  var setSize = function(width, img, data){
393
1251
  var curCandidate = data.curCan;
394
1252
 
@@ -400,7 +1258,7 @@
400
1258
  var bgImg, curCandidate, clear;
401
1259
 
402
1260
 
403
- if(knownWidths[url]){
1261
+ if(url in knownWidths){
404
1262
  setSize(knownWidths[url], img, data);
405
1263
  } else {
406
1264
  clear = function(){
@@ -418,11 +1276,18 @@
418
1276
  setSize(curCandidate.w, img, data);
419
1277
  }
420
1278
 
421
- bgImg = document.createElement('img');
1279
+ bgImg = document.createElement("img");
422
1280
 
423
1281
  bgImg.onload = function(){
424
1282
  knownWidths[url] = bgImg.naturalWidth || bgImg.width;
425
- if(url == img[curSrcProp]){
1283
+ if (!knownWidths[url]) {
1284
+ try {
1285
+ document.body.appendChild(bgImg);
1286
+ knownWidths[url] = bgImg.offsetWidth || bgImg.naturalWidth || bgImg.width;
1287
+ document.body.removeChild(bgImg);
1288
+ } catch (e) {}
1289
+ }
1290
+ if(url == img.src){
426
1291
  setSize(knownWidths[url], img, data);
427
1292
  }
428
1293
  clear();
@@ -442,7 +1307,7 @@
442
1307
 
443
1308
  var run = function(){
444
1309
  var i, len, imgData;
445
- var imgs = document.getElementsByTagName('img');
1310
+ var imgs = document.getElementsByTagName("img");
446
1311
  var options = {elements: []};
447
1312
 
448
1313
  ri.setupRun(options);
@@ -472,10 +1337,6 @@
472
1337
 
473
1338
  })();
474
1339
 
475
- if( !(curSrcProp in document.createElement("img")) ){
476
- curSrcProp = "src";
477
- }
478
-
479
1340
  ri.setSize = function( img ) {
480
1341
  var url;
481
1342
  var data = img[ ri.ns ];
@@ -488,14 +1349,14 @@
488
1349
  if ( !cfg.addSize || !curCandidate || data.dims ) {return;}
489
1350
  url = ri.makeUrl(curCandidate.url);
490
1351
 
491
- if(url == img[curSrcProp] && url !== data.pendingURLSize){
1352
+ if(url == img.src && url !== data.pendingURLSize){
492
1353
  loadBg(url, img, data);
493
1354
  }
494
1355
  };
495
1356
 
496
1357
 
497
- if(window.addEventListener){
498
- addEventListener('resize', reeval, false);
1358
+ if(window.addEventListener && !window.HTMLPictureElement){
1359
+ addEventListener("resize", reeval, false);
499
1360
  }
500
1361
 
501
1362
  if(!('addSize' in cfg)){
@@ -507,6 +1368,100 @@
507
1368
  reeval();
508
1369
  }));
509
1370
 
1371
+ (function( factory ) {
1372
+ "use strict";
1373
+ var interValId;
1374
+ var intervalIndex = 0;
1375
+ var run = function(){
1376
+ if ( window.respimage ) {
1377
+ factory( window.respimage );
1378
+ }
1379
+ if(window.respimage || intervalIndex > 9999){
1380
+ clearInterval(interValId);
1381
+ }
1382
+ intervalIndex++;
1383
+ };
1384
+ interValId = setInterval(run, 8);
1385
+
1386
+ run();
1387
+
1388
+ }( function( respimage ) {
1389
+ "use strict";
1390
+
1391
+ var ri = respimage._;
1392
+ var runningTests = 0;
1393
+ var setTypeValue = function(types, value){
1394
+ var i;
1395
+ for(i = 0; i < types.length; i++){
1396
+ ri.types[types[i]] = value;
1397
+ }
1398
+ };
1399
+
1400
+ if(window.HTMLPictureElement && !ri.cfg.uT){
1401
+ respimage.testTypeSupport = function(){};
1402
+ return;
1403
+ }
1404
+
1405
+ ri.types["image/bmp"] = true;
1406
+ ri.types["image/x-bmp"] = true;
1407
+
1408
+ respimage.testTypeSupport = function(types, url, width, useCanvas){
1409
+ if(typeof types == "string"){
1410
+ types = types.split(/\s*\,*\s+/g);
1411
+ }
1412
+ var canvas;
1413
+ var supports = "pending";
1414
+ var img = document.createElement('img');
1415
+ var onComplete = function(){
1416
+ runningTests--;
1417
+ setTypeValue(types, supports);
1418
+ if(runningTests < 1){
1419
+ respimage({reevaluate: true});
1420
+ }
1421
+ };
1422
+
1423
+ if(useCanvas){
1424
+ canvas = document.createElement('canvas');
1425
+ if(!canvas.getContext){
1426
+ setTypeValue(types, false);
1427
+ return;
1428
+ }
1429
+ }
1430
+
1431
+ img.onload = function(){
1432
+ var ctx;
1433
+ supports = true;
1434
+ if(width){
1435
+ supports = img.width == width;
1436
+ }
1437
+
1438
+ if(useCanvas){
1439
+ ctx = canvas.getContext('2d');
1440
+ ctx.drawImage(img, 0, 0);
1441
+ supports = ctx.getImageData(0, 0, 1, 1).data[3] === 0;
1442
+ }
1443
+ onComplete();
1444
+ };
1445
+
1446
+ img.onerror = function(){
1447
+ supports = false;
1448
+ onComplete();
1449
+ };
1450
+ runningTests++;
1451
+ setTypeValue(types, "pending");
1452
+ img.src = url;
1453
+ };
1454
+
1455
+
1456
+ respimage.testTypeSupport("image/webp", "data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==", 1);
1457
+ respimage.testTypeSupport("image/jp2 image/jpx image/jpm", "data:image/jp2;base64,/0//UQAyAAAAAAABAAAAAgAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAEBwEBBwEBBwEBBwEB/1IADAAAAAEAAAQEAAH/XAAEQED/ZAAlAAFDcmVhdGVkIGJ5IE9wZW5KUEVHIHZlcnNpb24gMi4wLjD/kAAKAAAAAABYAAH/UwAJAQAABAQAAf9dAAUBQED/UwAJAgAABAQAAf9dAAUCQED/UwAJAwAABAQAAf9dAAUDQED/k8+kEAGvz6QQAa/PpBABr994EAk//9k=", 1);
1458
+ respimage.testTypeSupport("image/vnd.ms-photo", "data:image/vnd.ms-photo;base64,SUm8AQgAAAAFAAG8AQAQAAAASgAAAIC8BAABAAAAAQAAAIG8BAABAAAAAQAAAMC8BAABAAAAWgAAAMG8BAABAAAAHwAAAAAAAAAkw91vA07+S7GFPXd2jckNV01QSE9UTwAZAYBxAAAAABP/gAAEb/8AAQAAAQAAAA==", 1);
1459
+ respimage.testTypeSupport("video/vnd.mozilla.apng video/x-apng video/png video/apng video/x-mng video/x-png", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg==", false, true);
1460
+
1461
+ }));
1462
+
1463
+
1464
+
510
1465
 
511
1466
  (function(){
512
1467