PageSourceSearch

https://infobeteg.hu/assets/js/slimmage/slimmage.js

js infobeteg.hu collected 2026-10-03 01:51:46 UTC 13,664 bytes, 331 lines download raw bytes

1/**
2 * @preserve Slimmage 0.4.2, use with ImageResizer. MIT/Apache2 dual licensed by Imazen 
3 */
4
5/* We often use string instead of dot notation to keep 
6   Closure Compiler's advanced mode from breaking APIs */
7/*jshint sub:true*/
8
9(function (w) { //w==window
10    // Enable strict mode
11    "use strict";
12
13    var s =  window['slimmage'] || {};
14    window['slimmage'] = s;
15    if (s['verbose'] === undefined) {           s['verbose'] = false;}
16    if (s['tryWebP'] === undefined) {           s['tryWebP'] = false;}
17    if (s['maxWidth'] === undefined) {          s['maxWidth'] = 2048;}
18    if (s['widthStep'] === undefined) {         s['widthStep'] = 160;}
19    if (s['jpegQuality'] === undefined) {       s['jpegQuality'] = 90;}
20    if (s['jpegRetinaQuality'] === undefined) { s['jpegRetinaQuality'] = 80;}
21    if (s['webpTimeout'] === undefined){        s['webpTimeout'] = 0;}
22    s['changed'] = [];
23
24    var log = function(){ if (s['verbose'] && w.console && w.console.log) try {w.console.log.apply(w.console,arguments);}catch(e){}};
25    s.beginWebPTest = function(){
26        if (!s['tryWebP'] || s._testingWebP) return;
27        s._testingWebP = true;
28
29        var WebP=new Image();
30        WebP.onload=WebP.onerror=function(){
31            s['webp'] = (WebP.height==2);
32            s._testingWebP = false;
33            if (s.cr) { s.cr(); }
34        };
35        WebP.src='data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
36    };
37    //test for webp support ASAP
38    s.beginWebPTest();
39
40    s.setAttr = function(elem, name, value){
41      name = name.toLowerCase();
42      if (name == "class"){ elem.className = value;}
43      else if (name == "tabindex") {elem.tabIndex = value;}
44      else if (name == "usemap") {elem.useMap = value;}
45      else{
46        elem.setAttribute(name,value);
47      }
48      
49    };
50    s['setAttribute'] = s.setAttr;
51
52    s.is_blank = function(v){ return v === "none" || v === null || v === undefined || v === "" || v === false;};
53    s['getCssValue'] = function(target, hyphenProp){
54      //See http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser
55
56      var val = typeof(window.getComputedStyle) != "undefined" && window.getComputedStyle(target, null).getPropertyValue(hyphenProp);
57
58      // Some browsers (IE8, Firefox 28) read "none" when not set. Others (IE6) respond with undefined. A value of
59      // "none" is invalid and would cause an exception or be interpreted as 
60      if (!s.is_blank(val)){ 
61        return val; 
62      }
63
64      if (target.currentStyle){
65        val = target.currentStyle[hyphenProp.replace(/([a-z])\-([a-z])/, function(a,b,c){ return b + c.toUpperCase();})] || target.currentStyle[hyphenProp];
66      }
67      
68      return s.is_blank(val) ? null : val;
69    };
70
71    s['getCssPixels'] = function(target, hyphenProp){
72      var val = s['getCssValue'](target,hyphenProp);
73
74      if (val === null || val === "0" || val === 0) return val;
75
76      //We can return pixels directly, but not other units
77      if (val.slice(-2) == "px") return parseFloat(val.slice(0,-2));
78
79      //Create a temporary sibling div to resolve units into pixels.
80      var temp = document.createElement("div");
81      temp.style.overflow = temp.style.visibility = "hidden"; 
82      temp.style.cssFloat = "none";
83      target.parentNode.appendChild(temp);  
84      temp.style.width = val;
85      var pixels = temp.offsetWidth;
86      target.parentNode.removeChild(temp);
87      return pixels;
88    };
89
90    s.nodesToArray = function (nodeList) {
91        var array = [];
92        // iterate backwards ensuring that length is an UInt32
93        for (var i = nodeList.length >>> 0; i--;) {
94            array[i] = nodeList[i];
95        }
96        return array;
97    };
98
99    /*
100      No URI decoding/encoding is perfomed on keys or values. Caller's responsibility.
101
102      vistor and mutator are applied to string.replace -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter
103      params:
104      1. entire pair, incl. (optional) &  and = 
105      2. '&' (if present)
106      3. key
107      4. value
108
109      mutator's result is honored. Must return param 1, or provide valid replacement.
110      
111      injector(query) is responsible for adding additional pairs if required. 
112      It must not produce a malformatted query.
113    */
114    s['mutateUrl'] = function(url, visitor,mutator,injector){
115      var m = /^([^?#]*)?(\?([^#]*))?(#.*)?/.exec(url);
116      var q = m[3] || '';
117
118      var qr = /(^&*|&+)([^&=]*)=?([^&]*)/g;
119      q.replace(qr, visitor); //read-only, to gather data
120
121      var newq = '?' + q.replace(qr, mutator).replace(/(?:^\?*&*)|(?:[?&]+$)/g,"").replace(/&&+/g,"&");
122
123      return (m[1] || '') + injector(newq) + (m[4] || '');
124    };
125
126    //Expects virtual, not device pixel width
127    s['getImageInfo'] = function (elementWidth, previousSrc, previousPixelWidth, previousElement) {
128        var data = {
129            'webp': s['webp'],
130            'width': elementWidth,
131            'dpr': window.devicePixelRatio || 1,
132            'src': previousSrc, 
133            'element': previousElement
134        };
135        //Determine quality percentage
136        var high_density = s['webp'] ? 65 : s['jpegRetinaQuality'];
137        var low_density = s['webp'] ? 78 : s['jpegQuality'];
138        data['quality'] = data['dpr'] > 1.49 ? high_density : low_density;
139      
140        //Calculate raw pixels using devicePixelRatio. Limit size to maxWidth.
141        var idealWidth = elementWidth * data['dpr']; 
142        //Minimize variants for caching improvements; round up to nearest multiple of widthStep
143        data['requestedWidth'] = Math.min(s['maxWidth'], //Limit size to maxWidth
144                                  Math.round( //Round in case widthStep isn't an integer
145                                    Math.ceil(idealWidth / s['widthStep']) * s['widthStep'] //Divide, ceiling, then multiply
146                                            )
147                                          );
148
149
150        var a = s['adjustImageParameters'];
151        if (a && typeof(a) === "function") {
152            a(data);
153        }
154        var finalWidth = data['requestedWidth'];
155
156        if (finalWidth > previousPixelWidth) {
157            //Never request a smaller image once the larger one has already started loading
158            var u = {}; //For storing raw pairs
159            var c = {}; //For storing relevant parsed info
160            var newSrc = s['mutateUrl'](
161              previousSrc,
162              //Visitor
163              function(_,d, k,v){
164                u[k.toLowerCase()] = v;
165              }, 
166              //Mutator
167              function(p,d,k,v){
168
169                //Parse existing values so we can make educated calculations for width/height
170                if (c.zoom === undefined){
171                  c.zoom = parseFloat(u.zoom || 1);
172                  if (isNaN(c.zoom)){ c.zoom = 1; }
173                  c.w = (finalWidth / c.zoom).toFixed();
174                }
175                if (c.ratio === undefined){
176                  var w = parseFloat(u.width || u.w || u.maxwidth);
177                  var h = parseFloat(u.height || u.h || u.maxheight);
178                  if (!isNaN(w) && !isNaN(h) && w > 0 && h > 0){
179                    c.ratio = w/h;
180                    c.h = (((finalWidth / c.zoom) / w) * h).toFixed();
181                  }else{
182                    c.ratio = 'noclue';
183                  }
184                }
185                
186                if (k.match(/^format$/i) && data['webp']) { return d + "format=webp"; }
187                if (k.match(/^quality/i)) { return d + "quality=" + data['quality']; }
188                
189                if (k.match(/^(w|width|maxwidth)$/i)) { return d + k + "=" + c.w;}
190                if (k.match(/^(h|height|maxheight)$/i)) { return d + k + "=" + c.h;}
191                
192                return p;
193              }, 
194              //Injector
195              function(q){ return q;});
196            
197            return {'src': newSrc, 'data-pixel-width': finalWidth};
198        }
199        return null;
200    };
201    s['adjustImageSrc'] = function (img, previousSrc) {
202
203        var cssMaxWidth = s['getCssPixels'](img, 'max-width');
204        var result = s['getImageInfo'](cssMaxWidth,
205                                       previousSrc,
206                                       img.getAttribute('data-pixel-width') | 0,
207                                       img);
208        
209        if (result){
210          img.src = result['src'];
211          s.setAttr(img,'data-pixel-width',result['data-pixel-width']);
212          if (s['enforceCss']){
213            if (cssMaxWidth < result['data-pixel-width']){
214              img.style.width = s['getCssValue'](img,'max-width'); 
215              s.setAttr(img,'data-width-enforced',true);
216            }else{
217              img.style.width = 'auto';
218            }
219          }
220          s['changed'].push(img);
221          log("Slimming: updating " + result['src']);
222        }else if (s['enforceCss'] && img.getAttribute('data-width-enforced')){
223          var imageWidth = parseFloat(img.getAttribute('data-pixel-width'));
224          if (!isNaN(imageWidth) && cssMaxWidth >= imageWidth){
225            img.style.width = 'auto';
226            img.removeAttribute('data-width-enforced');
227          }
228        }
229
230    };
231    s.cr = function (delay) {
232        var i, il, j, jl, k, kl;
233
234        if (s.timeoutid > 0) w.clearTimeout(s.timeoutid);
235        s.timeoutid = 0;
236
237        if (s._testingWebP && s['webpTimeout'] > 0 && !s.webp_waiting){
238          s.webp_waiting = true;
239          delay = s['webpTimeout'];
240        }
241        if (delay && delay > 0) {
242            s.timeoutid = w.setTimeout(s.cr, delay);
243            return;
244        }
245        var stopwatch = new Date().getTime();
246
247        var newImages = 0;
248        //1. Copy images out of noscript tags, but hide 'src' attribute as data-src
249        var n = s.nodesToArray(w.document.getElementsByTagName("noscript"));
250        for (i = 0, il = n.length; i < il; i++) {
251            var ns = n[i];
252            if (ns.getAttribute("data-slimmage") !== null) {
253                
254                var div = w.document.createElement('div');
255                var contents = (ns.textContent || ns.innerHTML);
256                if (!contents || contents.replace(/[\s\t\r\n]+/,"").length === 0){
257                    //IE doesn't let us touch noscript, so we have to use attributes.
258                    var img = new Image();
259                    for (var ai = 0; ai < ns.attributes.length; ai++) {
260                        var a = ns.attributes[ai];
261                        if (a && a.specified && a.name.indexOf("data-img-") === 0){
262                            s.setAttr(img,a.name.slice(9 - a.name.length),a.value);
263                        }
264                    }
265                    div.appendChild(img);
266                }else{
267                    //noscript isn't part of DOM, so we have to recreate it, unescaping html, src->data-src 
268                    div.innerHTML = contents.replace(/\s+src\s*=\s*(['"])/i, " data-src=$1").
269                        replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
270                }
271                //Clear source values before we add it back to the dom, ensure data-slimmage is set.
272                var childImages = div.getElementsByTagName("img");
273                for (j = 0, jl = childImages.length; j < jl; j++) {
274                    var ci = childImages[j];
275                    if (ci.src !== null && ci.src.length > 0) {
276                        s.setAttr(ci,"data-src", ci.src);
277                        ci.src = "";
278                    }
279                    s.setAttr(ci,"data-slimmage", true);
280                    ns.parentNode.insertBefore(ci, ns);
281                    newImages++;
282                }
283                //2. Remove old noscript tags
284                ns.parentNode.removeChild(ns);
285            }
286        }
287
288        //3. Let plugins inject custom behavior
289        if('function' === typeof s['beforeAdjustSrc']) {
290            s['beforeAdjustSrc']();
291        }
292
293        //4. Find images with data-slimmage and run adjustImageSrc.
294        var totalImages = 0;
295        var images = s.nodesToArray(w.document.getElementsByTagName("img"));
296        for (k = 0, kl = images.length; k < kl; k++) {
297            if (images[k].getAttribute("data-slimmage") !== null) {
298                var previousSrc = images[k].getAttribute("data-src") || images[k].src;
299                s['adjustImageSrc'](images[k], previousSrc);
300                totalImages++;
301            }
302        }
303
304        var changed = s['changed'].slice();
305        s['changed'].length = 0;
306
307        //5. Callback when ready
308        if((changed.length > 0 || !s.readyCalled)  && 'function' === typeof s['readyCallback']) {
309            s['readyCallback'](changed);
310            s.readyCalled = true;
311        }
312        
313        log("Slimmage: restored " + newImages + " images from noscript tags, checked " + totalImages + " images, changed " + changed.length + ". " + (new Date().getTime() - stopwatch) + "ms");
314    };
315
316    s['checkResponsiveImages'] = s.cr;
317    // Run on resize and domready (w.load as a fallback)
318    if (w.addEventListener) {
319        w.addEventListener("resize", function () { s.cr(500); }, false);
320        w.addEventListener("DOMContentLoaded", function () {
321            s.cr();
322            // Run once only
323            w.removeEventListener("load", s.cr, false);
324        }, false);
325        w.addEventListener("load", s.cr, false);
326    } else if (w.attachEvent) {
327        w.attachEvent("onload", s.cr);
328        w.attachEvent("onresize",  function () { s.cr(500); });
329    }
330    
331}(this));

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.