PageSourceSearch

https://southamptonair.org.uk/Scripts/utils/ResizeSensor.js?v=3.229.10.17%20(77.107)

js southamptonair.org.uk collected 2026-10-07 17:52:58 UTC 10,406 bytes, 310 lines download raw bytes

1'use strict';
2
3/**
4 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level
5 * directory of this distribution and at
6 * https://github.com/marcj/css-element-queries/blob/master/LICENSE.
7 */
8(function (root, factory) {
9    if (typeof define === "function" && define.amd) {
10        define(factory);
11    } else if (typeof exports === "object") {
12        module.exports = factory();
13    } else {
14        root.ResizeSensor = factory();
15    }
16}(typeof window !== 'undefined' ? window : this, function () {
17
18    // Make sure it does not throw in a SSR (Server Side Rendering) situation
19    if (typeof window === "undefined") {
20        return null;
21    }
22    // Only used for the dirty checking, so the event callback count is limited to max 1 call per fps per sensor.
23    // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and
24    // would generate too many unnecessary events.
25    var requestAnimationFrame = window.requestAnimationFrame ||
26        window.mozRequestAnimationFrame ||
27        window.webkitRequestAnimationFrame ||
28        function (fn) {
29            return window.setTimeout(fn, 20);
30        };
31
32    /**
33     * Iterate over each of the provided element(s).
34     *
35     * @param {HTMLElement|HTMLElement[]} elements
36     * @param {Function}                  callback
37     */
38    function forEachElement(elements, callback){
39        var elementsType = Object.prototype.toString.call(elements);
40        var isCollectionTyped = ('[object Array]' === elementsType
41            || ('[object NodeList]' === elementsType)
42            || ('[object HTMLCollection]' === elementsType)
43            || ('[object Object]' === elementsType)
44            || ('undefined' !== typeof jQuery && elements instanceof jQuery) //jquery
45            || ('undefined' !== typeof Elements && elements instanceof Elements) //mootools
46        );
47        var i = 0, j = elements.length;
48        if (isCollectionTyped) {
49            for (; i < j; i++) {
50                callback(elements[i]);
51            }
52        } else {
53            callback(elements);
54        }
55    }
56
57    /**
58    * Get element size
59    * @param {HTMLElement} element
60    * @returns {Object} {width, height}
61    */
62    function getElementSize(element) {
63        if (!element.getBoundingClientRect) {
64            return {
65                width: element.offsetWidth,
66                height: element.offsetHeight
67            }
68        }
69
70        var rect = element.getBoundingClientRect();
71        return {
72            width: Math.round(rect.width),
73            height: Math.round(rect.height)
74        }
75    }
76
77    /**
78     * Class for dimension change detection.
79     *
80     * @param {Element|Element[]|Elements|jQuery} element
81     * @param {Function} callback
82     *
83     * @constructor
84     */
85    var ResizeSensor = function(element, callback) {
86
87        var observer;
88
89        /**
90         *
91         * @constructor
92         */
93        function EventQueue() {
94            var q = [];
95            this.add = function(ev) {
96                q.push(ev);
97            };
98
99            var i, j;
100            this.call = function(sizeInfo) {
101                for (i = 0, j = q.length; i < j; i++) {
102                    q[i].call(this, sizeInfo);
103                }
104            };
105
106            this.remove = function(ev) {
107                var newQueue = [];
108                for(i = 0, j = q.length; i < j; i++) {
109                    if(q[i] !== ev) newQueue.push(q[i]);
110                }
111                q = newQueue;
112            };
113
114            this.length = function() {
115                return q.length;
116            }
117        }
118
119        /**
120         *
121         * @param {HTMLElement} element
122         * @param {Function}    resized
123         */
124        function attachResizeEvent(element, resized) {
125            if (!element) return;
126            if (element.resizedAttached) {
127                element.resizedAttached.add(resized);
128                return;
129            }
130
131            element.resizedAttached = new EventQueue();
132            element.resizedAttached.add(resized);
133
134            element.resizeSensor = document.createElement('div');
135            element.resizeSensor.dir = 'ltr';
136            element.resizeSensor.className = 'resize-sensor';
137            var style = 'position: absolute; left: -10px; top: -10px; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden; max-width: 100%';
138            var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
139
140            element.resizeSensor.style.cssText = style;
141            element.resizeSensor.innerHTML =
142                '<div class="resize-sensor-expand" style="' + style + '">' +
143                    '<div style="' + styleChild + '"></div>' +
144                '</div>' +
145                '<div class="resize-sensor-shrink" style="' + style + '">' +
146                    '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
147                '</div>';
148            element.appendChild(element.resizeSensor);
149
150            var computedStyle = window.getComputedStyle(element);
151            var position = computedStyle ? computedStyle.getPropertyValue('position') : null;
152            if ('absolute' !== position && 'relative' !== position && 'fixed' !== position) {
153                element.style.position = 'relative';
154            }
155
156            var expand = element.resizeSensor.childNodes[0];
157            var expandChild = expand.childNodes[0];
158            var shrink = element.resizeSensor.childNodes[1];
159
160            var dirty, rafId;
161            var size = getElementSize(element);
162            var lastWidth = size.width;
163            var lastHeight = size.height;
164            var initialHiddenCheck = true, resetRAF_id;
165
166
167            var resetExpandShrink = function () {
168                expandChild.style.width = '100000px';
169                expandChild.style.height = '100000px';
170
171                expand.scrollLeft = 100000;
172                expand.scrollTop = 100000;
173
174                shrink.scrollLeft = 100000;
175                shrink.scrollTop = 100000;
176            };
177
178            var reset = function() {
179                // Check if element is hidden
180                if (initialHiddenCheck) {
181                    if (!expand.scrollTop && !expand.scrollLeft) {
182
183                        // reset
184                        resetExpandShrink();
185
186                        // Check in next frame
187                        if (!resetRAF_id){
188                            resetRAF_id = requestAnimationFrame(function(){
189                                resetRAF_id = 0;
190
191                                reset();
192                            });
193                        }
194
195                        return;
196                    } else {
197                        // Stop checking
198                        initialHiddenCheck = false;
199                    }
200                }
201
202                resetExpandShrink();
203            };
204            element.resizeSensor.resetSensor = reset;
205
206            var onResized = function() {
207                rafId = 0;
208
209                if (!dirty) return;
210
211                lastWidth = size.width;
212                lastHeight = size.height;
213
214                if (element.resizedAttached) {
215                    element.resizedAttached.call(size);
216                }
217            };
218
219            var onScroll = function() {
220                size = getElementSize(element);
221                dirty = size.width !== lastWidth || size.height !== lastHeight;
222
223                if (dirty && !rafId) {
224                    rafId = requestAnimationFrame(onResized);
225                }
226
227                reset();
228            };
229
230            var addEvent = function(el, name, cb) {
231                if (el.attachEvent) {
232                    el.attachEvent('on' + name, cb);
233                } else {
234                    el.addEventListener(name, cb);
235                }
236            };
237
238            addEvent(expand, 'scroll', onScroll);
239            addEvent(shrink, 'scroll', onScroll);
240
241            // Fix for custom Elements
242            requestAnimationFrame(reset);
243        }
244
245        if (typeof ResizeObserver !== "undefined") {
246            observer = new ResizeObserver(function(element){
247                forEachElement(element, function (elem) {
248                    callback.call(
249                        this,
250                        {
251                            width: elem.contentRect.width,
252                            height: elem.contentRect.height
253                        }
254                   );
255                });
256            });
257            if (element !== undefined) {
258                forEachElement(element, function(elem){
259                   observer.observe(elem);
260                });
261            }
262        }
263        else {
264            forEachElement(element, function(elem){
265                attachResizeEvent(elem, callback);
266            });
267        }
268
269        this.detach = function(ev) {
270            if (typeof ResizeObserver != "undefined") {
271                forEachElement(element, function(elem){
272                    observer.unobserve(elem);
273                });
274            }
275            else {
276                ResizeSensor.detach(element, ev);
277            }
278        };
279
280        this.reset = function() {
281            element.resizeSensor.resetSensor();
282        };
283    };
284
285    ResizeSensor.reset = function(element, ev) {
286        forEachElement(element, function(elem){
287            elem.resizeSensor.resetSensor();
288        });
289    };
290
291    ResizeSensor.detach = function(element, ev) {
292        forEachElement(element, function(elem){
293            if (!elem) return;
294            if(elem.resizedAttached && typeof ev === "function"){
295                elem.resizedAttached.remove(ev);
296                if(elem.resizedAttached.length()) return;
297            }
298            if (elem.resizeSensor) {
299                if (elem.contains(elem.resizeSensor)) {
300                    elem.removeChild(elem.resizeSensor);
301                }
302                delete elem.resizeSensor;
303                delete elem.resizedAttached;
304            }
305        });
306    };
307
308    return ResizeSensor;
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.