PageSourceSearch

https://www.gov.hk/js/libs/grayscale.js?20161109.151941

js www.gov.hk collected 2026-09-24 08:29:37 UTC 13,215 bytes, 310 lines download raw bytes

1/*
2 * -- grayscale.js --
3 * Copyright (C) James Padolsey (http://james.padolsey.com)
4 *
5 */
6
7var grayscale = (function(){
8    
9    var config = {
10            colorProps: ['color','backgroundColor','borderBottomColor','borderTopColor','borderLeftColor','borderRightColor','backgroundImage'],
11            externalImageHandler : {
12                /* Grayscaling externally hosted images does not work
13                   - Use these functions to handle those images as you so desire */
14                /* Out of convenience these functions are also used for browsers
15                   like Chrome that do not support CanvasContext.getImageData */
16                init : function(el, src) {
17                    if (el.nodeName.toLowerCase() === 'img') {
18                        // Is IMG element...
19                    } else {
20                        // Is background-image element:
21                        // Default - remove background images
22                        data(el).backgroundImageSRC = src;
23                        el.style.backgroundImage = '';
24                    }
25                },
26                reset : function(el) {
27                    if (el.nodeName.toLowerCase() === 'img') {
28                        // Is IMG element...
29                    } else {
30                        // Is background-image element:
31                        el.style.backgroundImage = 'url(' + (data(el).backgroundImageSRC || '') + ')';
32                    }
33                }
34            }
35        },
36        log = function(){
37            try { window.console.log.apply(console, arguments); }
38            catch(e) {};
39        },
40        isExternal = function(url) {
41            // Checks whether URL is external: 'CanvasContext.getImageData'
42            // only works if the image is on the current domain.
43            return (new RegExp('https?://(?!' + window.location.hostname + ')')).test(url);
44        },
45        data = (function(){
46            
47            var cache = [0],
48            expando = 'data' + (+new Date());
49            
50            return function(elem) {
51                var cacheIndex = elem[expando],
52                    nextCacheIndex = cache.length;
53                if(!cacheIndex) {
54                    cacheIndex = elem[expando] = nextCacheIndex;
55                    cache[cacheIndex] = {};
56                }
57                return cache[cacheIndex];
58            };
59            
60        })(),
61        desatIMG = function(img, prepare, realEl) {
62            
63            // realEl is only set when img is temp (for BG images)
64            
65            var canvas = document.createElement('canvas'),
66                context = canvas.getContext('2d'),
67                height = img.naturalHeight || img.offsetHeight || img.height,
68                width = img.naturalWidth || img.offsetWidth || img.width,
69                imgData;
70                
71            canvas.height = height;
72            canvas.width = width;
73            context.drawImage(img, 0, 0);
74            try {
75                imgData = context.getImageData(0, 0, width, height);
76            } catch(e) {}
77            
78            if (prepare) {
79                desatIMG.preparing = true;
80                // Slowly recurse through pixels for prep,
81                // :: only occurs on grayscale.prepare()
82                var y = 0;
83                (function(){
84                    
85                    if (!desatIMG.preparing) { return; }
86                    
87                    if (y === height) {
88                        // Finished!
89                        context.putImageData(imgData, 0, 0, 0, 0, width, height);
90                        realEl ? (data(realEl).BGdataURL = canvas.toDataURL())
91                               : (data(img).dataURL = canvas.toDataURL())
92                    }
93                    
94                    for (var x = 0; x < width; x++) {
95                        var i = (y * width + x) * 4;
96                        // Apply Monoschrome level across all channels:
97                        imgData.data[i] = imgData.data[i+1] = imgData.data[i+2] =
98                        RGBtoGRAYSCALE(imgData.data[i], imgData.data[i+1], imgData.data[i+2]);
99                    }
100                    
101                    y++;
102                    setTimeout(arguments.callee, 0);
103                    
104                })();
105                return;
106            } else {
107                // If desatIMG was called without 'prepare' flag
108                // then cancel recursion and proceed with force! (below)
109                desatIMG.preparing = false;
110            }
111            
112            for (var y = 0; y < height; y++) {
113                for (var x = 0; x < width; x++) {
114                    var i = (y * width + x) * 4;
115                    // Apply Monoschrome level across all channels:
116                    imgData.data[i] = imgData.data[i+1] = imgData.data[i+2] =
117                    RGBtoGRAYSCALE(imgData.data[i], imgData.data[i+1], imgData.data[i+2]);
118                }
119            }
120            
121            context.putImageData(imgData, 0, 0, 0, 0, width, height);
122            return canvas;
123        
124        },
125        getStyle = function(el, prop) {
126            var style = document.defaultView && document.defaultView.getComputedStyle ? 
127                        document.defaultView.getComputedStyle(el, null)[prop]
128                        : el.currentStyle[prop];
129            // If format is #FFFFFF: (convert to RGB)
130            if (style && /^#[A-F0-9]/i.test(style)) {
131                    var hex = style.match(/[A-F0-9]{2}/ig);
132                    style = 'rgb(' + parseInt(hex[0], 16) + ','
133                                   + parseInt(hex[1], 16) + ','
134                                   + parseInt(hex[2], 16) + ')';
135            }
136            return style;
137        },
138        RGBtoGRAYSCALE = function(r,g,b) {
139            // Returns single monochrome figure:
140            return parseInt( (0.2125 * r) + (0.7154 * g) + (0.0721 * b), 10 );
141        },
142        getAllNodes = function(context) {
143            var all = Array.prototype.slice.call(context.getElementsByTagName('*'));
144            all.unshift(context);
145            return all;
146        };
147        
148    var init = function(context) {
149        
150        // Handle if a DOM collection is passed instead of a single el:
151        if (context && context[0] && context.length && context[0].nodeName) {
152            // Is a DOM collection:
153            var allContexts = Array.prototype.slice.call(context),
154                cIndex = -1, cLen = allContexts.length;
155            while (++cIndex<cLen) { init.call(this, allContexts[cIndex]); }
156            return;
157        }
158        
159        context = context || document.documentElement;
160        
161        if (!document.createElement('canvas').getContext) {
162            context.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)';
163            context.style.zoom = 1;
164            return;
165        }
166        
167        var all = getAllNodes(context),
168            i = -1, len = all.length;
169            
170        while (++i<len) {
171            var cur = all[i];
172            
173            if (cur.nodeName.toLowerCase() === 'img') {
174                var src = cur.getAttribute('src');
175                if(!src) { continue; }
176                if (isExternal(src)) {
177                    config.externalImageHandler.init(cur, src);
178                } else {
179                    data(cur).realSRC = src;
180                    try {
181                        // Within try statement just encase there's no support....
182                        cur.src = data(cur).dataURL || desatIMG(cur).toDataURL();
183                    } catch(e) { config.externalImageHandler.init(cur, src); }
184                }
185                
186            } else {
187                for (var pIndex = 0, pLen = config.colorProps.length; pIndex < pLen; pIndex++) {
188                    var prop = config.colorProps[pIndex],
189                    style = getStyle(cur, prop);
190                    if (!style) {continue;}
191                    if (cur.style[prop]) {
192                        data(cur)[prop] = style;
193                    }
194                    // RGB color:
195                    if (style.substring(0,4) === 'rgb(') {
196                        var monoRGB = RGBtoGRAYSCALE.apply(null, style.match(/\d+/g));
197                        cur.style[prop] = style = 'rgb(' + monoRGB + ',' + monoRGB + ',' + monoRGB + ')';
198                        continue;
199                    }
200                    // Background Image:
201                    if (style.indexOf('url(') > -1) {
202                        var urlPatt = /\(['"]?(.+?)['"]?\)/,
203                            url = style.match(urlPatt)[1];
204                        if (isExternal(url)) {
205                            config.externalImageHandler.init(cur, url);
206                            data(cur).externalBG = true;
207                            continue;
208                        }
209                        // data(cur).BGdataURL refers to caches URL (from preparation)
210                        try {
211                            var imgSRC = data(cur).BGdataURL || (function(){
212                                    var temp = document.createElement('img');
213                                    temp.src = url;
214                                    return desatIMG(temp).toDataURL();
215                                })();
216                            
217                            cur.style[prop] = style.replace(urlPatt, function(_, url){
218                                return '(' + imgSRC + ')';
219                            });
220                        } catch(e) { config.externalImageHandler.init(cur, url); }
221                    }
222                }
223            }
224        }
225        
226    };
227    
228    init.reset = function(context) {
229        // Handle if a DOM collection is passed instead of a single el:
230        if (context && context[0] && context.length && context[0].nodeName) {
231            // Is a DOM collection:
232            var allContexts = Array.prototype.slice.call(context),
233                cIndex = -1, cLen = allContexts.length;
234            while (++cIndex<cLen) { init.reset.call(this, allContexts[cIndex]); }
235            return;
236        }
237        context = context || document.documentElement;
238        if (!document.createElement('canvas').getContext) {
239            context.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=0)';
240            return;
241        }
242        var all = getAllNodes(context),
243            i = -1, len = all.length;
244        while (++i<len) {
245            var cur = all[i];
246            if (cur.nodeName.toLowerCase() === 'img') {
247                var src = cur.getAttribute('src');
248                if (isExternal(src)) {
249                    config.externalImageHandler.reset(cur, src);
250                }
251                cur.src = data(cur).realSRC || src;
252            } else {
253                for (var pIndex = 0, pLen = config.colorProps.length; pIndex < pLen; pIndex++) {
254                    if (data(cur).externalBG) {
255                        config.externalImageHandler.reset(cur);
256                    }
257                    var prop = config.colorProps[pIndex];
258                    cur.style[prop] = data(cur)[prop] || '';
259                }
260            }
261        }
262    };
263    
264    init.prepare = function(context) {
265        
266        // Handle if a DOM collection is passed instead of a single el:
267        if (context && context[0] && context.length && context[0].nodeName) {
268            // Is a DOM collection:
269            var allContexts = Array.prototype.slice.call(context),
270                cIndex = -1, cLen = allContexts.length;
271            while (++cIndex<cLen) { init.prepare.call(null, allC
271ontexts[cIndex]); }
272            return;
273        }
274        
275        // Slowly recurses through all elements
276        // so as not to lock up on the user.
277        
278        context = context || document.documentElement;
279        
280        if (!document.createElement('canvas').getContext) { return; }
281        
282        var all = getAllNodes(context),
283            i = -1, len = all.length;
284        
285        while (++i<len) {
286            var cur = all[i];
287            if (data(cur).skip) { return; }
288            if (cur.nodeName.toLowerCase() === 'img') {
289                if (cur.getAttribute('src') && !isExternal(cur.src)) {
290                    desatIMG(cur, true);
291                }
292                
293            } else {
294                var style = getStyle(cur, 'backgroundImage');
295                if (style.indexOf('url(') > -1) {
296                    var urlPatt = /\(['"]?(.+?)['"]?\)/,
297                        url = style.match(urlPatt)[1];
298                    if (!isExternal(url)) {
299                        var temp = document.createElement('img');
300                        temp.src = url;
301                        desatIMG(temp, true, cur);
302                    }
303                }
304            }
305        }
306    };
307    
308    return init;
309
310})();

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.