140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik/** 240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * Copyright Marc J. Schmidt. See the LICENSE file at the top-level 340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * directory of this distribution and at 440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * https://github.com/marcj/css-element-queries/blob/master/LICENSE. 540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik */ 640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik; 740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik(function() { 840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik /** 1040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * Class for dimension change detection. 1140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * 1240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @param {Element|Element[]|Elements|jQuery} element 1340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @param {Function} callback 1440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * 1540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @constructor 1640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik */ 1740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.ResizeSensor = function(element, callback) { 1840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik /** 1940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * 2040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @constructor 2140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik */ 2240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik function EventQueue() { 2340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.q = []; 2440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.add = function(ev) { 2540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.q.push(ev); 2640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 2740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 2840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var i, j; 2940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.call = function() { 3040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik for (i = 0, j = this.q.length; i < j; i++) { 3140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.q[i].call(); 3240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 3340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 3440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 3540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 3640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik /** 3740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @param {HTMLElement} element 3840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @param {String} prop 3940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @returns {String|Number} 4040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik */ 4140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik function getComputedStyle(element, prop) { 4240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (element.currentStyle) { 4340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik return element.currentStyle[prop]; 4440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } else if (window.getComputedStyle) { 4540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik return window.getComputedStyle(element, null).getPropertyValue(prop); 4640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } else { 4740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik return element.style[prop]; 4840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 4940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 5040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 5140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik /** 5240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * 5340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @param {HTMLElement} element 5440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik * @param {Function} resized 5540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik */ 5640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik function attachResizeEvent(element, resized) { 5740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (!element.resizedAttached) { 5840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizedAttached = new EventQueue(); 5940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizedAttached.add(resized); 6040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } else if (element.resizedAttached) { 6140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizedAttached.add(resized); 6240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik return; 6340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 6440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 6540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizeSensor = document.createElement('div'); 6640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizeSensor.className = 'resize-sensor'; 6740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;'; 6840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var styleChild = 'position: absolute; left: 0; top: 0;'; 6940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 7040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizeSensor.style.cssText = style; 7140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizeSensor.innerHTML = 7240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik '<div class="resize-sensor-expand" style="' + style + '">' + 7340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik '<div style="' + styleChild + '"></div>' + 7440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik '</div>' + 7540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik '<div class="resize-sensor-shrink" style="' + style + '">' + 7640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' + 7740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik '</div>'; 7840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.appendChild(element.resizeSensor); 7940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 8040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (!{fixed: 1, absolute: 1}[getComputedStyle(element, 'position')]) { 8140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.style.position = 'relative'; 8240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 8340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 8440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var expand = element.resizeSensor.childNodes[0]; 8540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var expandChild = expand.childNodes[0]; 8640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var shrink = element.resizeSensor.childNodes[1]; 8740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var shrinkChild = shrink.childNodes[0]; 8840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 8940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var lastWidth, lastHeight; 9040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 9140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var reset = function() { 9240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik expandChild.style.width = expand.offsetWidth + 10 + 'px'; 9340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik expandChild.style.height = expand.offsetHeight + 10 + 'px'; 9440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik expand.scrollLeft = expand.scrollWidth; 9540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik expand.scrollTop = expand.scrollHeight; 9640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik shrink.scrollLeft = shrink.scrollWidth; 9740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik shrink.scrollTop = shrink.scrollHeight; 9840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik lastWidth = element.offsetWidth; 9940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik lastHeight = element.offsetHeight; 10040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 10140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 10240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik reset(); 10340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 10440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var changed = function() { 10540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (element.resizedAttached) { 10640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.resizedAttached.call(); 10740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 10840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 10940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 11040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var addEvent = function(el, name, cb) { 11140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (el.attachEvent) { 11240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik el.attachEvent('on' + name, cb); 11340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } else { 11440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik el.addEventListener(name, cb); 11540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 11640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 11740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 11840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik addEvent(expand, 'scroll', function() { 11940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (element.offsetWidth > lastWidth || element.offsetHeight > lastHeight) { 12040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik changed(); 12140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 12240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik reset(); 12340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }); 12440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 12540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik addEvent(shrink, 'scroll',function() { 12640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (element.offsetWidth < lastWidth || element.offsetHeight < lastHeight) { 12740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik changed(); 12840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 12940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik reset(); 13040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }); 13140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 13240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 13340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if ("[object Array]" === Object.prototype.toString.call(element) 13440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik || ('undefined' !== typeof jQuery && element instanceof jQuery) //jquery 13540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik || ('undefined' !== typeof Elements && element instanceof Elements) //mootools 13640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik ) { 13740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik var i = 0, j = element.length; 13840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik for (; i < j; i++) { 13940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik attachResizeEvent(element[i], callback); 14040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 14140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } else { 14240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik attachResizeEvent(element, callback); 14340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 14440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 14540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.detach = function() { 14640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik ResizeSensor.detach(element); 14740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 14840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 14940f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 15040f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik this.ResizeSensor.detach = function(element) { 15140f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik if (element.resizeSensor) { 15240f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik element.removeChild(element.resizeSensor); 15340f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik delete element.resizeSensor; 15440f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik delete element.resizedAttached; 15540f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik } 15640f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik }; 15740f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik 15840f8da8088c9cd699f672242d0cdc3d677353bf8Chris Craik})();