1/** 2 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level 3 * directory of this distribution and at 4 * https://github.com/marcj/css-element-queries/blob/master/LICENSE. 5 */ 6; 7(function (root, factory) { 8 if (typeof define === "function" && define.amd) { 9 define(factory); 10 } else if (typeof exports === "object") { 11 module.exports = factory(); 12 } else { 13 root.ResizeSensor = factory(); 14 } 15}(this, function () { 16 17 // Only used for the dirty checking, so the event callback count is limted to max 1 call per fps per sensor. 18 // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and 19 // would generate too many unnecessary events. 20 var requestAnimationFrame = window.requestAnimationFrame || 21 window.mozRequestAnimationFrame || 22 window.webkitRequestAnimationFrame || 23 function (fn) { 24 return window.setTimeout(fn, 20); 25 }; 26 27 /** 28 * Iterate over each of the provided element(s). 29 * 30 * @param {HTMLElement|HTMLElement[]} elements 31 * @param {Function} callback 32 */ 33 function forEachElement(elements, callback){ 34 var elementsType = Object.prototype.toString.call(elements); 35 var isCollectionTyped = ('[object Array]' === elementsType 36 || ('[object NodeList]' === elementsType) 37 || ('[object HTMLCollection]' === elementsType) 38 || ('undefined' !== typeof jQuery && elements instanceof jQuery) //jquery 39 || ('undefined' !== typeof Elements && elements instanceof Elements) //mootools 40 ); 41 var i = 0, j = elements.length; 42 if (isCollectionTyped) { 43 for (; i < j; i++) { 44 callback(elements[i]); 45 } 46 } else { 47 callback(elements); 48 } 49 } 50 51 /** 52 * Class for dimension change detection. 53 * 54 * @param {Element|Element[]|Elements|jQuery} element 55 * @param {Function} callback 56 * 57 * @constructor 58 */ 59 var ResizeSensor = function(element, callback) { 60 /** 61 * 62 * @constructor 63 */ 64 function EventQueue() { 65 var q = []; 66 this.add = function(ev) { 67 q.push(ev); 68 }; 69 70 var i, j; 71 this.call = function() { 72 for (i = 0, j = q.length; i < j; i++) { 73 q[i].call(); 74 } 75 }; 76 77 this.remove = function(ev) { 78 var newQueue = []; 79 for(i = 0, j = q.length; i < j; i++) { 80 if(q[i] !== ev) newQueue.push(q[i]); 81 } 82 q = newQueue; 83 } 84 85 this.length = function() { 86 return q.length; 87 } 88 } 89 90 /** 91 * @param {HTMLElement} element 92 * @param {String} prop 93 * @returns {String|Number} 94 */ 95 function getComputedStyle(element, prop) { 96 if (element.currentStyle) { 97 return element.currentStyle[prop]; 98 } else if (window.getComputedStyle) { 99 return window.getComputedStyle(element, null).getPropertyValue(prop); 100 } else { 101 return element.style[prop]; 102 } 103 } 104 105 /** 106 * 107 * @param {HTMLElement} element 108 * @param {Function} resized 109 */ 110 function attachResizeEvent(element, resized) { 111 if (!element.resizedAttached) { 112 element.resizedAttached = new EventQueue(); 113 element.resizedAttached.add(resized); 114 } else if (element.resizedAttached) { 115 element.resizedAttached.add(resized); 116 return; 117 } 118 119 element.resizeSensor = document.createElement('div'); 120 element.resizeSensor.className = 'resize-sensor'; 121 var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;'; 122 var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;'; 123 124 element.resizeSensor.style.cssText = style; 125 element.resizeSensor.innerHTML = 126 '<div class="resize-sensor-expand" style="' + style + '">' + 127 '<div style="' + styleChild + '"></div>' + 128 '</div>' + 129 '<div class="resize-sensor-shrink" style="' + style + '">' + 130 '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' + 131 '</div>'; 132 element.appendChild(element.resizeSensor); 133 134 if (getComputedStyle(element, 'position') == 'static') { 135 element.style.position = 'relative'; 136 } 137 138 var expand = element.resizeSensor.childNodes[0]; 139 var expandChild = expand.childNodes[0]; 140 var shrink = element.resizeSensor.childNodes[1]; 141 142 var reset = function() { 143 expandChild.style.width = 100000 + 'px'; 144 expandChild.style.height = 100000 + 'px'; 145 146 expand.scrollLeft = 100000; 147 expand.scrollTop = 100000; 148 149 shrink.scrollLeft = 100000; 150 shrink.scrollTop = 100000; 151 }; 152 153 reset(); 154 var dirty = false; 155 156 var dirtyChecking = function() { 157 if (!element.resizedAttached) return; 158
159 if (dirty) { 160 element.resizedAttached.call(); 161 dirty = false; 162 } 163 164 requestAnimationFrame(dirtyChecking); 165 }; 166 167 requestAnimationFrame(dirtyChecking); 168 var lastWidth, lastHeight; 169 var cachedWidth, cachedHeight; //useful to not query offsetWidth twice 170 171 var onScroll = function() { 172 if ((cachedWidth = element.offsetWidth) != lastWidth || (cachedHeight = element.offsetHeight) != lastHeight) { 173 dirty = true; 174 175 lastWidth = cachedWidth; 176 lastHeight = cachedHeight; 177 } 178 reset(); 179 }; 180 181 var addEvent = function(el, name, cb) { 182 if (el.attachEvent) { 183 el.attachEvent('on' + name, cb); 184 } else { 185 el.addEventListener(name, cb); 186 } 187 }; 188 189 addEvent(expand, 'scroll', onScroll); 190 addEvent(shrink, 'scroll', onScroll); 191 } 192 193 forEachElement(element, function(elem){ 194 attachResizeEvent(elem, callback); 195 }); 196 197 this.detach = function(ev) { 198 ResizeSensor.detach(element, ev); 199 }; 200 }; 201 202 ResizeSensor.detach = function(element, ev) { 203 forEachElement(element, function(elem){ 204 if(elem.resizedAttached && typeof ev == "function"){ 205 elem.resizedAttached.remove(ev); 206 if(elem.resizedAttached.length()) return; 207 } 208 if (elem.resizeSensor) { 209 if (elem.contains(elem.resizeSensor)) { 210 elem.removeChild(elem.resizeSensor); 211 } 212 delete elem.resizeSensor; 213 delete elem.resizedAttached; 214 } 215 }); 216 }; 217 218 return ResizeSensor; 219 220}));
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.