summaryrefslogtreecommitdiffstats
path: root/web/lib/ResizeSensor.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/lib/ResizeSensor.js')
-rwxr-xr-xweb/lib/ResizeSensor.js166
1 files changed, 166 insertions, 0 deletions
diff --git a/web/lib/ResizeSensor.js b/web/lib/ResizeSensor.js
new file mode 100755
index 000000000..e5ce136a8
--- /dev/null
+++ b/web/lib/ResizeSensor.js
@@ -0,0 +1,166 @@
+/**
+ * Copyright Marc J. Schmidt. See the LICENSE file at the top-level
+ * directory of this distribution and at
+ * https://github.com/marcj/css-element-queries/blob/master/LICENSE.
+ */
+;
+(function() {
+
+ /**
+ * Class for dimension change detection.
+ *
+ * @param {Element|Element[]|Elements|jQuery} element
+ * @param {Function} callback
+ *
+ * @constructor
+ */
+ this.ResizeSensor = function(element, callback) {
+ /**
+ *
+ * @constructor
+ */
+ function EventQueue() {
+ this.q = [];
+ this.add = function(ev) {
+ this.q.push(ev);
+ };
+
+ var i, j;
+ this.call = function() {
+ for (i = 0, j = this.q.length; i < j; i++) {
+ this.q[i].call();
+ }
+ };
+ }
+
+ /**
+ * @param {HTMLElement} element
+ * @param {String} prop
+ * @returns {String|Number}
+ */
+ function getComputedStyle(element, prop) {
+ if (element.currentStyle) {
+ return element.currentStyle[prop];
+ } else if (window.getComputedStyle) {
+ return window.getComputedStyle(element, null).getPropertyValue(prop);
+ } else {
+ return element.style[prop];
+ }
+ }
+
+ /**
+ *
+ * @param {HTMLElement} element
+ * @param {Function} resized
+ */
+ function attachResizeEvent(element, resized) {
+ if (!element.resizedAttached) {
+ element.resizedAttached = new EventQueue();
+ element.resizedAttached.add(resized);
+ } else if (element.resizedAttached) {
+ element.resizedAttached.add(resized);
+ return;
+ }
+
+ element.resizeSensor = document.createElement('div');
+ element.resizeSensor.className = 'resize-sensor';
+ var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
+ var styleChild = 'position: absolute; left: 0; top: 0;';
+
+ element.resizeSensor.style.cssText = style;
+ element.resizeSensor.innerHTML =
+ '<div class="resize-sensor-expand" style="' + style + '">' +
+ '<div style="' + styleChild + '"></div>' +
+ '</div>' +
+ '<div class="resize-sensor-shrink" style="' + style + '">' +
+ '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
+ '</div>';
+ element.appendChild(element.resizeSensor);
+
+ if (!{fixed: 1, absolute: 1}[getComputedStyle(element, 'position')]) {
+ element.style.position = 'relative';
+ }
+
+ var expand = element.resizeSensor.childNodes[0];
+ var expandChild = expand.childNodes[0];
+ var shrink = element.resizeSensor.childNodes[1];
+ var shrinkChild = shrink.childNodes[0];
+
+ var lastWidth, lastHeight;
+
+ var reset = function() {
+ expandChild.style.width = expand.offsetWidth + 10 + 'px';
+ expandChild.style.height = expand.offsetHeight + 10 + 'px';
+ expand.scrollLeft = expand.scrollWidth;
+ expand.scrollTop = expand.scrollHeight;
+ shrink.scrollLeft = shrink.scrollWidth;
+ shrink.scrollTop = shrink.scrollHeight;
+ lastWidth = element.offsetWidth;
+ lastHeight = element.offsetHeight;
+ };
+
+ reset();
+
+ var changed = function() {
+ if (element.resizedAttached) {
+ element.resizedAttached.call();
+ }
+ };
+
+ var addEvent = function(el, name, cb) {
+ if (el.attachEvent) {
+ el.attachEvent('on' + name, cb);
+ } else {
+ el.addEventListener(name, cb);
+ }
+ };
+
+ var onScroll = function() {
+ if (element.offsetWidth != lastWidth || element.offsetHeight != lastHeight) {
+ changed();
+ }
+ reset();
+ }
+
+ addEvent(expand, 'scroll', onScroll);
+ addEvent(shrink, 'scroll', onScroll);
+ }
+
+ var elementType = Object.prototype.toString.call(element);
+ var isCollectionTyped = ('[object Array]' === elementType
+ || ('[object NodeList]' === elementType)
+ || ('[object HTMLCollection]' === elementType)
+ || ('undefined' !== typeof jQuery && element instanceof jQuery) //jquery
+ || ('undefined' !== typeof Elements && element instanceof Elements) //mootools
+ );
+
+ if (isCollectionTyped) {
+ var i = 0, j = element.length;
+ for (; i < j; i++) {
+ attachResizeEvent(element[i], callback);
+ }
+ } else {
+ attachResizeEvent(element, callback);
+ }
+
+ this.detach = function() {
+ if (isCollectionTyped) {
+ var i = 0, j = element.length;
+ for (; i < j; i++) {
+ ResizeSensor.detach(element[i]);
+ }
+ } else {
+ ResizeSensor.detach(element);
+ }
+ };
+ };
+
+ this.ResizeSensor.detach = function(element) {
+ if (element.resizeSensor) {
+ element.removeChild(element.resizeSensor);
+ delete element.resizeSensor;
+ delete element.resizedAttached;
+ }
+ };
+
+})();