1/* BG Srcset 1.0 */ 2(function(){ 3 'use strict'; 4 5 var bgsrcset = function(){ 6 7 this.called = false; 8 this.callonce = true; 9 this.compat(); 10 }; 11 12 bgsrcset.prototype.init = function(target, callback){ 13 //retina bool 14 this.retina = window.devicePixelRatio > 1; 15 16 //storage for our elements 17 this.elements = []; 18 19 //global onload callback for imagery 20 this.callback = typeof callback === 'function' ? callback : function(){}; 21 22 //window width, for responsive handling 23 this.curwidth = this.getWidth(); 24 25 //get our input and turn it into an element list of some sort 26 var elems = this.gather(target); 27 28 //parse the element input 29 for(var i = 0, l = elems.length; i < l; i++){ this.parse(elems[i]); } 30 //this.set(); 31 this.resize(); 32 }; 33 34 /* -----------* / 35 Fix compatibility issues* 36 *only down to IE8 37 / *----------- */ 38 39 bgsrcset.prototype.compat = function(){ 40 var d = document; 41 /* check for getElementsByClassName */ 42 if(typeof d.getElementsByClassName !== 'function'){ 43 d.getElementsByClassName = function(str){ 44 return d.querySelectorAll('.' + str); 45 }; 46 } 47 48 /* check for .trim() */ 49 if (!String.prototype.trim) { 50 String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');}; 51 } 52 53 /*------------------------* / 54 Check for Event Listener 55 / *------*/ 56 if(!d.addEventListener){ 57 this.addEvent = function(elem, evName, fn){ 58 elem.attachEvent('on'+evName,function(e) { 59 fn(e || window.event); 60 }); 61 }; 62 } 63 64 }; 65 66 /* -----------* / 67 Gather elements 68 / *----------- */ 69 bgsrcset.prototype.gather = function(target){ 70 var autotypes = ['HTMLCollection', 'NodeList']; 71 var e = target; 72 var type = (e.nodeType) ? 'Object' : Object.prototype.toString.call( e ).replace(/^\[object |\]$/g, ''); 73 74 var func = 'parse' + type; 75 76 if(autotypes.indexOf(type) > -1){ 77 return e; 78 } 79 80 if( this[func] ){ 81 return this[func](e); 82 } 83 84 return []; 85 }; 86 87 bgsrcset.prototype.parseObject = function( target ) { 88 return (target.nodeType) ? [target] : []; 89 }; 90 91 bgsrcset.prototype.parseArray = function( target ) { 92 return target; 93 }; 94 95 bgsrcset.prototype.parseString = function( target ) { 96 97 var d = document; 98 var e = target.trim(); 99 var sel = e[0]; 100 var elems = []; 101 102 switch(true){ 103 /* class */ 104 case sel === '.': 105 elems = d.getElementsByClassName(e.substring(1)); 106 break; 107 /* id */ 108 case sel === '#': 109 elems.push(d.getElementById(e.substring(1))); 110 break; 111 /* tag */ 112 case /^[a-zA-Z]+$/.test(e): 113 elems = d.getElementsByTagName(e); 114 break; 115 /* unknown */ 116 default: 117 elems = []; 118 } 119 120 return elems; 121 }; 122 123 /* -----------* / 124 Parse datasrc 125 / *----------- */ 126 bgsrcset.prototype.parse = function(obj){ 127 //our data to parase 128 var bgss = obj.getAttribute('data-bg-srcset'); 129 /* exit if no attribute */ 130 if(bgss === null){ return false; } 131 132 /* create new element object */ 133 this.elements.push({}); 134 135 /* split up sets */ 136 var set = bgss.split(','); 137 var attr = ''; 138 var curelem = this.elements[this.elements.length - 1]; 139 140 141 curelem.node = obj; 142 curelem.srcset = []; 143 144 /* loop through sets to define breakpoints */ 145 for(var i = 0, l = set.length; i < l; i++){ 146 curelem.srcset.push({}); 147 attr = set[i].trim(); 148 var attrs = attr.split(' '); 149 var a; 150 var e; 151 var t; 152 /* since we can't know the order of the values, starting another loop */ 153 for(var attrc = 0, attrl = attrs.length; attrc < attrl; attrc++){ 154 a = attrs[attrc]; 155 e = curelem.srcset[i]; //current attribute 156 t = a.length-1; 157 switch(true){ 158 case a.trim() === "":
159 //in case of extra white spaces 160 continue; 161 case a[t] !== 'w' && a[a.length-1] !== 'x': 162 e.src = a; 163 break; 164 case a[t] === 'w': 165 e.width = parseInt( a.slice( 0, -1 ) ); 166 break; 167 case a[t] === 'x': 168 e.retina = ( parseInt( a.slice( 0, -1 ) ) > 1); 169 break; 170 } 171 if(! e.width ){ e.width = Number.POSITIVE_INFINITY; } //set to the top 172 if(! e.retina ){ e.retina = false; } 173 } 174 } 175 }; 176 177 /* -----------* / 178 Set image 179 / *----------- */ 180 bgsrcset.prototype.set = function(){ 181 for(var i = 0, l = this.elements.length; i < l; i++){ 182 this.setSingle(i); 183 184 } 185 }; 186 187 bgsrcset.prototype.setSingle = function(id){ 188 189 var width = 0, 190 elem = this.elements[id], 191 comparray = [], 192 best = 0, 193 _this = this; 194 195 width = this.getWidth(); //elem.node.offsetWidth; 196 197 elem.srcset = elem.srcset.sort(dynamicSort("width")); 198 199 for(var i = 0, l = elem.srcset.length; i < l; i++){ 200 if(elem.srcset[i].width < width){ 201 continue; 202 } 203 comparray.push( elem.srcset[i] ); 204 } 205 if(comparray.length === 0){ 206 comparray.push(elem.srcset[elem.srcset.length -1]); 207 } 208 209 best = comparray[0]; 210 211 if(comparray.length > 1 && comparray[0].width === comparray[1].width){ 212 best = (comparray[0].retina !== this.retina) ? comparray[1] : comparray[0]; 213 } 214 215 if( best.src !== undefined && best.src !== 'null'){ 216 var img = new Image(); 217 var done = false; 218 219 img.onload = img.onreadystatechange = function() { 220 221 if ( !done && (!this.readyState || 222 this.readyState === "loaded" || this.readyState === "complete") ) { 223 done = true; 224 225 elem.node.style.backgroundImage = "url('" + best.src + "')"; 226 227 /* only fire the callback on initial load, not resize events */ 228 if (!_this.called) { 229 230 _this.callback(elem); 231 _this.called = _this.callonce; 232 233 } 234 235 } 236 237 }; 238 239 img.src = best.src; 240 }else{ 241 elem.node.style.backgroundImage = ""; 242 } 243 244 245 }; 246 247 /* -----------* / 248 Handle Resize 249 / *----------- */ 250 bgsrcset.prototype.resize = function(){ 251 var _this = this, 252 resizeTimer = setTimeout(function(){}, 0); 253 254 this.addEvent(window, 'resize',function() { 255 clearTimeout(resizeTimer); 256 resizeTimer = setTimeout(function(){ 257 var w = _this.getWidth(); 258 if ( w !== _this.curwidth ){ 259 _this.curwidth = w; 260 _this.set(); 261 } 262 }, 250); 263 }); 264 }; 265 266 bgsrcset.prototype.addEvent = function(elem, evName, fn){ 267 elem.addEventListener(evName,fn,false); 268 }; 269 270 bgsrcset.prototype.getWidth = function(){ 271 var w, d, e, g; 272 w = window; 273 d = document; 274 e = d.documentElement; 275 g = d.getElementsByTagName('body')[0]; 276 277 return w.innerWidth || e.clientWidth || g.clientWidth; 278 }; 279 280 function dynamicSort(property) { 281 var sortOrder = 1; 282 if(property[0] === "-") { 283 sortOrder = -1; 284 property = property.substr(1); 285 } 286 return function (a,b) { 287 var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; 288 return result * sortOrder; 289 }; 290 } 291 292 window.bgsrcset = bgsrcset; 293})(); 294 295var bgss = new bgsrcset(); 296 297bgss.callonce = false; 298 299bgss.init( '.bg-image-srcset' );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.