PageSourceSearch

https://contents.kyobobook.co.kr/resources/vendors/css-element-queries/ResizeSensor.js

js kyobobook.co.kr collected 2026-09-24 08:29:34 UTC 8,691 bytes, 263 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() {
98                for (i = 0, j = q.length; i < j; i++) {
99                    q[i].call();
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 = 'position: absolute; left: -10px; top: -10px; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;';
135            var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
136
137            element.resizeSensor.style.cssText = style;
138            element.resizeSensor.innerHTML =
139                '<div class="resize-sensor-expand" style="' + style + '">' +
140                    '<div style="' + styleChild + '"></div>' +
141                '</div>' +
142                '<div class="resize-sensor-shrink" style="' + style + '">' +
143                    '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
144                '</div>';
145            element.appendChild(element.resizeSensor);
146
147            var position = window.getComputedStyle(element).getPropertyPriority('position');
148            if ('absolute' !== position && 'relative' !== position && 'fixed' !== position) {
149                element.style.position = 'relative';
150            }
151
152            var expand = element.resizeSensor.childNodes[0];
153            var expandChild = expand.childNodes[0];
154            var shrink = element.resizeSensor.childNodes[1];
155            var dirty, rafId, newWidth, newHeight;
156            var size = getElementSize(element);
157            var lastWidth = size.width;
158            var lastHeight = size.height;
159
160            var reset = function() {
161                //set display to block, necessary otherwise hidden elements won't ever work
162                var invisible = element.offsetWidth === 0 && element.offsetHeight === 0;
163
164                if (invisible) {
165                    var saveDisplay = element.style.display;
166                    element.style.display = 'block';
167                }
168
169                expandChild.style.width = '100000px';
170                expandChild.style.height = '100000px';
171
172                expand.scrollLeft = 100000;
173                expand.scrollTop = 100000;
174
175                shrink.scrollLeft = 100000;
176                shrink.scrollTop = 100000;
177
178                if (invisible) {
179                    element.style.display = saveDisplay;
180                }
181            };
182            element.resizeSensor.resetSensor = reset;
183
184            var onResized = function() {
185                rafId = 0;
186
187                if (!dirty) return;
188
189                lastWidth = newWidth;
190                lastHeight = newHeight;
191
192                if (element.resizedAttached) {
193                    element.resizedAttached.call();
194                }
195            };
196
197            var onScroll = function() {
198                var size = getElementSize(element);
199                var newWidth = size.width;
200                var newHeight = size.height;
201                dirty = newWidth != lastWidth || newHeight != lastHeight;
202
203                if (dirty && !rafId) {
204                    rafId = requestAnimationFrame(onResized);
205                }
206
207                reset();
208            };
209
210            var addEvent = function(el, name, cb) {
211                if (el.attachEvent) {
212                    el.attachEvent('on' + name, cb);
213                } else {
214                    el.addEventListener(name, cb);
215                }
216            };
217
218            addEvent(expand, 'scroll', onScroll);
219            addEvent(shrink, 'scroll', onScroll);
220            
221			// Fix for custom Elements
222			requestAnimationFrame(reset);
223        }
224
225        forEachElement(element, function(elem){
226            attachResizeEvent(elem, callback);
227        });
228
229        this.detach = function(ev) {
230            ResizeSensor.detach(element, ev);
231        };
232
233        this.reset = function() {
234            element.resizeSensor.resetSensor();
235        };
236    };
237
238    ResizeSensor.reset = function(element, ev) {
239        forEachElement(element, function(elem){
240            elem.resizeSensor.resetSensor();
241        });
242    };
243
244    ResizeSensor.detach = function(element, ev) {
245        forEachElement(element, function(elem){
246            if (!elem) return;
247            if(elem.resizedAttached && typeof ev === "function"){
248                elem.resizedAttached.remove(ev);
249                if(elem.resizedAttached.length()) return;
250            }
251            if (elem.resizeSensor) {
252                if (elem.contains(elem.resizeSensor)) {
253                    elem.removeChild(elem.resizeSensor);
254                }
255                delete elem.resizeSensor;
256                delete elem.resizedAttached;
257            }
258        });
259    };
260
261    return ResizeSensor;
262
263}));

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.