PageSourceSearch

https://www.ncpc.org.sg/assets/js/jquery.resize-sensor.js

js ncpc.org.sg collected 2026-09-25 23:57:12 UTC 10,103 bytes, 302 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         *
88         * @constructor
89         */
90        function EventQueue() {
91            var q = [];
92            this.add = function(ev) {
93                q.push(ev);
94            };
95
96            var i, j;
97            this.call = function(sizeInfo) {
98                for (i = 0, j = q.length; i < j; i++) {
99                    q[i].call(this, sizeInfo);
100                }
101            };
102
103            this.remove = function(ev) {
104                var newQueue = [];
105                for(i = 0, j = q.length; i < j; i++) {
106                    if(q[i] !== ev) newQueue.push(q[i]);
107                }
108                q = newQueue;
109            };
110
111            this.length = function() {
112                return q.length;
113            }
114        }
115
116        /**
117         *
118         * @param {HTMLElement} element
119         * @param {Function}    resized
120         */
121        function attachResizeEvent(element, resized) {
122            if (!element) return;
123            if (element.resizedAttached) {
124                element.resizedAttached.add(resized);
125                return;
126            }
127
128            element.resizedAttached = new EventQueue();
129            element.resizedAttached.add(resized);
130
131            element.resizeSensor = document.createElement('div');
132            element.resizeSensor.dir = 'ltr';
133            element.resizeSensor.className = 'resize-sensor';
134            var style = 'pointer-events: none; position: absolute; left: 0px; top: 0px; right: 0; bottom: 0; ' +
135                'overflow: hidden; z-index: -1; visibility: hidden; max-width: 100%;';
136            var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
137
138            element.resizeSensor.style.cssText = style;
139            element.resizeSensor.innerHTML =
140                '<div class="resize-sensor-expand" style="' + style + '">' +
141                    '<div style="' + styleChild + '"></div>' +
142                '</div>' +
143                '<div class="resize-sensor-shrink" style="' + style + '">' +
144                    '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
145                '</div>';
146            element.appendChild(element.resizeSensor);
147
148            var computedStyle = window.getComputedStyle(element);
149            var position = computedStyle ? computedStyle.getPropertyValue('position') : null;
150            if ('absolute' !== position && 'relative' !== position && 'fixed' !== position) {
151                element.style.position = 'relative';
152            }
153
154            var expand = element.resizeSensor.childNodes[0];
155            var expandChild = expand.childNodes[0];
156            var shrink = element.resizeSensor.childNodes[1];
157            var dirty, rafId;
158            var size = getElementSize(element);
159            var lastWidth = size.width;
160            var lastHeight = size.height;
161            var initialHiddenCheck = true;
162            var lastAnimationFrame = 0;
163
164            var resetExpandShrink = function () {
165                var width = element.offsetWidth;
166                var height = element.offsetHeight;
167
168                expandChild.style.width = (width + 10) + 'px';
169                expandChild.style.height = (height + 10) + 'px';
170
171                expand.scrollLeft = width + 10;
172                expand.scrollTop = height + 10;
173
174                shrink.scrollLeft = width + 10;
175                shrink.scrollTop = height + 10;
176            };
177
178            var reset = function() {
179                // Check if element is hidden
180                if (initialHiddenCheck) {
181                    var invisible = element.offsetWidth === 0 && element.offsetHeight === 0;
182                    if (invisible) {
183                        // Check in next frame
184                        if (!lastAnimationFrame){
185                            lastAnimationFrame = requestAnimationFrame(function(){
186                                lastAnimationFrame = 0;
187
188                                reset();
189                            });
190                        }
191
192                        return;
193                    } else {
194                        // Stop checking
195                        initialHiddenCheck = false;
196                    }
197                }
198
199                resetExpandShrink();
200            };
201            element.resizeSensor.resetSensor = reset;
202
203            var onResized = function() {
204                rafId = 0;
205
206                if (!dirty) return;
207
208                lastWidth = size.width;
209                lastHeight = size.height;
210
211                if (element.resizedAttached) {
212                    element.resizedAttached.call(size);
213                }
214            };
215
216            var onScroll = function() {
217                size = getElementSize(element);
218                dirty = size.width !== lastWidth || size.height !== lastHeight;
219
220                if (dirty && !rafId) {
221                    rafId = requestAnimationFrame(onResized);
222                }
223
224                reset();
225            };
226
227            var addEvent = function(el, name, cb) {
228                if (el.attachEvent) {
229                    el.attachEvent('on' + name, cb);
230                } else {
231                    el.addEventListener(name, cb);
232                }
233            };
234
235            addEvent(expand, 'scroll', onScroll);
236            addEvent(shrink, 'scroll', onScroll);
237
238            // Fix for custom Elements
239            requestAnimationFrame(reset);
240        }
241
242        forEachElement(element, function(elem){
243            attachResizeEvent(elem, callback);
244        });
245
246        this.detach = function(ev) {
247            ResizeSensor.detach(element, ev);
248        };
249
250        this.reset = function() {
251            element.resizeSensor.resetSensor();
252        };
253    };
254
255    ResizeSensor.reset = function(element) {
256        forEachElement(element, function(elem){
257            elem.resizeSensor.resetSensor();
258        });
259    };
260
261    ResizeSensor.detach = function(element, ev) {
262        forEachElement(element, function(elem){
263            if (!elem) return;
264            if(elem.resizedAttached && typeof ev === "function"){
265                elem.resizedAttached.remove(ev);
266                if(elem.resizedAttached.length()) return;
267            }
268            if (elem.resizeSensor) {
269                if (elem.contains(elem.resizeSensor)) {
270                    elem.removeChild(elem.resizeSensor);
271                }
272                delete elem.resizeSensor;
273                delete elem.resizedAttached;
274            }
275        });
276    };
277
278    if (typeof MutationObserver !== "undefined") {
279        var observer = new MutationObserver(function (mutations) {
280            for (var i in mutations) {
281                if (mutations.hasOwnProperty(i)) {
282                    var items = mutations[i].addedNodes;
283                    for (var j = 0; j < items.length; j++) {
284                        if (items[j].resizeSensor) {
285                            ResizeSensor.reset(items[j]);
286                        }
287                    }
288                }
289            }
290        });
291
292        document.addEventListener("DOMContentLoaded", function (event) {
293            observer.observe(document.body, {
294                childList: true,
295                subtree: true,
296            });
297        });
298    }
299
300    return ResizeSensor;
301
302}));

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.