1function dynamicThumbnail(url) { 2 $.each(url, function(key, data) { 3 var onReady = function(img, downloadUrl) { 4 img.attr("src", downloadUrl); 5 //console.log(downloadUrl); 6 img.on("error", function() { 7 onError(img); 8 }); 9 }; 10 11 var onError = function(img) { 12 img.attr("src", _global.baseUrl + "/img/not-available.png"); 13 }; 14 15 var image = $('#thumb_'+key); 16 if(_global.proxyImage === 1) { 17 var pp = new PagePeekerHelper(image, data, onReady, onError); 18 pp.poll(); 19 } else { 20 onReady(image, data.thumb); 21 } 22 }); 23} 24 25$(document).ready(function(){ 26 $("a.disabled, li.disabled a").click(function(){ 27 return false; 28 }) 29}); 30 31// Constructor 32function PagePeekerHelper(image, data, onReady, onError) { 33 $.ajaxSetup({ cache: false }); 34 this.proxy = _global.baseUrl+'/index.php/proxy'; 35 this.data = data; 36 this.onReady = onReady; 37 this.onError = onError; 38 this.image = image; 39 this.pollTime = 20; // In seconds 40 this.execLimit = 3; // If after x requests PP willn't response with status "Ready", then clear interval to avoid ddos attack. 41} 42 43PagePeekerHelper.prototype.poll = function() { 44 var self = this, 45 size = this.data.size || 'm', 46 url = this.data.url || '', 47 proxyReset = this.proxy + "?" + $.param({ 48 size: size, 49 url: url, 50 method: 'reset' 51 }), 52 53 proxyPoll = this.proxy + "?" + $.param({ 54 size: size, 55 url: url, 56 method: 'poll' 57 }), 58 limit = this.execLimit, 59 i = 0, 60 isFirstCall = true; 61 62 // Flush the image 63 $.get(proxyReset, function() { 64 //console.log("Reseting " + url); 65 66 var pollUntilReady = function(cb) { 67 //console.log("Polling " + url + " " + (i + 1) + " times"); 68 69 $.getJSON(proxyPoll, function(data) { 70 //console.log("Received", data); 71 var isReady = (data && data.IsReady) || 0; 72 if(isReady) { 73 //console.log("The " + url + " is ready: " + isReady); 74 self.onReady.apply(self, [self.image, self.data.thumb]); 75 return true; 76 } 77 if(data && data.Error) { 78 self.onError.apply(self, [self.image]); 79 return true; 80 } 81 cb(); 82 }).fail(function() { 83 //console.log('Failed to request local proxy script. Clearing the timeout'); 84 self.onError.apply(self, [self.image]); 85 }); 86 }; 87 88 89 (function pollThumbnail() { 90 var timeout = isFirstCall ? 0 : self.pollTime * 1000; 91 setTimeout(function() { 92 pollUntilReady(function() { 93 //console.log("Async " + url + " has done"); 94 isFirstCall = false; 95 i++; 96 if(i < limit) { 97 pollThumbnail(); 98 } else { 99 //console.log("Reached limit of reuqests for " + url); 100 self.onError.apply(self, [self.image]); 101 } 102 }); 103 }, timeout); 104 })(); 105 106 }).fail(function() { 107 self.onError.apply(self, [self.image]); 108 }); 109}; 110 111var WrHelper = (function () { 112 return { 113 isSameArray: function (a1, a2) { 114 var copy = a2.slice(), 115 i = 0, 116 l = a1.length 117 ; 118 for(; i < l; i++) { 119 var index = copy.indexOf(a1[i]); 120 if(index === -1) { 121 return false; 122 } else { 123 copy.splice(index, 1); 124 } 125 } 126 return copy.length === 0; 127 }, 128 } 129})(); 130 131var WrPsi = (function () { 132 var baseApiUrl = 'https://googlechrome.github.io/lighthouse/viewer/'; 133 134 return function (o) { 135 var options = $.extend({}, { 136 'i18nEnterFullscreen': 'Enter fullscreen mode', 137 'i18nExitFullscreen': 'Exit fullscreen mode', 138 'iframeWrapperSelector': '.psi__iframe-wrapper',
139 'analyzeBtnSelector': '.psi__analyze-btn', 140 'url': '', 141 'locale': 'en', 142 'runInstantly': false, 143 'categorySelector': '[data-psi-category]', // must be checkbox 144 'strategySelector': '[name="psi__strategy"]', // must be radio 145 }, o); 146 147 var category$ = $(options.categorySelector); 148 var strategy$ = $(options.strategySelector); 149 var iframeWrapper$ = $(options.iframeWrapperSelector); 150 var btnAnalyze$ = $(options.analyzeBtnSelector); 151 152 var currentCategories = []; 153 var currentStrategy = null; 154 var isFullscreen = false; 155 156 btnAnalyze$.on("click", function (e) { 157 e.preventDefault(); 158 analyze(); 159 }); 160 161 if(options.runInstantly) { 162 analyze(); 163 } 164 165 return { 166 destroy: function () { 167 isFullscreen = false; 168 destroy(iframeWrapper$); 169 } 170 }; 171 172 // 173 // Instance function 174 // 175 176 function analyze() { 177 var selectedCategories = getCheckedValues(category$); 178 var selectedStrategy = getFirstChecked(strategy$); 179 180 if(WrHelper.isSameArray(currentCategories, selectedCategories) && currentStrategy === selectedStrategy) { 181 //console.log(`Skip!`); 182 return; 183 } 184 185 destroy(iframeWrapper$); 186 187 currentStrategy = selectedStrategy; 188 currentCategories = selectedCategories; 189 190 var src = buildIframeSrc({ 191 strategy: selectedStrategy, 192 category: selectedCategories, 193 locale: options.locale, 194 url: options.url, 195 }); 196 197 var btnToggleView$ = $("<button>", { 198 text: isFullscreen ? options.i18nExitFullscreen : options.i18nEnterFullscreen, 199 class: "btn btn-danger psi__btn-view-mode" + (isFullscreen ? " psi__btn-view-mode-fullscreen" : " psi__btn-view-mode-normal"), 200 }).on("click", function (e) { 201 e.preventDefault(); 202 if(isFullscreen) { 203 isFullscreen = false; 204 iframeWrapper$.removeClass('psi__fullscreen').addClass('psi__content-view'); 205 $(document.body).removeClass('psi__body-fullscreen'); 206 $(this).text(options.i18nEnterFullscreen).removeClass('psi__btn-view-mode-fullscreen').addClass('psi__btn-view-mode-normal'); 207 } else { 208 isFullscreen = true; 209 iframeWrapper$.removeClass('psi__content-view').addClass('psi__fullscreen'); 210 $(document.body).addClass('psi__body-fullscreen'); 211 $(this).text(options.i18nExitFullscreen).removeClass('psi__btn-view-mode-normal').addClass('psi__btn-view-mode-fullscreen'); 212 } 213 }); 214 215 var iframe$ = $('<iframe>', { 216 src: src, 217 }); 218 219 iframeWrapper$.addClass(isFullscreen ? "psi__fullscreen" : "psi__content-view"); 220 221 iframeWrapper$.append( 222 btnToggleView$, 223 iframe$, 224 ); 225 } 226 }; 227 228 // 229 // Psi Helpers 230 // 231 232 function destroy(iframeWrapper$) { 233 iframeWrapper$.empty(); 234 } 235 236 function getCheckedValues(selector$) { 237 var selected = []; 238 selector$.each(function () { 239 if($(this).is(":checked")) { 240 selected.push($(this).val()); 241 } 242 }); 243 return selected; 244 } 245 246 function getFirstChecked(selector$) { 247 var selected = getCheckedValues(selector$); 248 return selected.length > 0 ? selected[0] : ""; 249 } 250 251 function encode(a) { 252 return a.map(function (item) { 253 return Array.isArray(item) ? encode(item) : encodeURIComponent(item.k)+'='+encodeURIComponent(item.v); 254 }).join('&'); 255 } 256 257 function buildIframeSrc(params) { 258 params = params || {}; 259 params.strategy = params.strategy || 'desktop'; 260 params.locale = params.locale || 'en'; 261 params.category = params.category || []; 262 params.url = params.url || ''; 263 264 return baseApiUrl + '?' + encode([ 265 {k: "psiurl", v: params.url}, 266 {k: "strategy", v: params.strategy}, 267 params.category.map(function (item) { 268 return {k: "category", v: item}; 269 }), 270 {k: "locale", v: params.locale} 271 ]); 272 } 273})(); 274 275
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.