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.