]> arthur.barton.de Git - netdata.git/blob - web/lib/ResizeSensor.js
added resize functionality to all charts with legend
[netdata.git] / web / lib / ResizeSensor.js
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() {
8
9     /**
10      * Class for dimension change detection.
11      *
12      * @param {Element|Element[]|Elements|jQuery} element
13      * @param {Function} callback
14      *
15      * @constructor
16      */
17     this.ResizeSensor = function(element, callback) {
18         /**
19          *
20          * @constructor
21          */
22         function EventQueue() {
23             this.q = [];
24             this.add = function(ev) {
25                 this.q.push(ev);
26             };
27
28             var i, j;
29             this.call = function() {
30                 for (i = 0, j = this.q.length; i < j; i++) {
31                     this.q[i].call();
32                 }
33             };
34         }
35
36         /**
37          * @param {HTMLElement} element
38          * @param {String}      prop
39          * @returns {String|Number}
40          */
41         function getComputedStyle(element, prop) {
42             if (element.currentStyle) {
43                 return element.currentStyle[prop];
44             } else if (window.getComputedStyle) {
45                 return window.getComputedStyle(element, null).getPropertyValue(prop);
46             } else {
47                 return element.style[prop];
48             }
49         }
50
51         /**
52          *
53          * @param {HTMLElement} element
54          * @param {Function}    resized
55          */
56         function attachResizeEvent(element, resized) {
57             if (!element.resizedAttached) {
58                 element.resizedAttached = new EventQueue();
59                 element.resizedAttached.add(resized);
60             } else if (element.resizedAttached) {
61                 element.resizedAttached.add(resized);
62                 return;
63             }
64
65             element.resizeSensor = document.createElement('div');
66             element.resizeSensor.className = 'resize-sensor';
67             var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;';
68             var styleChild = 'position: absolute; left: 0; top: 0;';
69
70             element.resizeSensor.style.cssText = style;
71             element.resizeSensor.innerHTML =
72                 '<div class="resize-sensor-expand" style="' + style + '">' +
73                     '<div style="' + styleChild + '"></div>' +
74                 '</div>' +
75                 '<div class="resize-sensor-shrink" style="' + style + '">' +
76                     '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
77                 '</div>';
78             element.appendChild(element.resizeSensor);
79
80             if (!{fixed: 1, absolute: 1}[getComputedStyle(element, 'position')]) {
81                 element.style.position = 'relative';
82             }
83
84             var expand = element.resizeSensor.childNodes[0];
85             var expandChild = expand.childNodes[0];
86             var shrink = element.resizeSensor.childNodes[1];
87             var shrinkChild = shrink.childNodes[0];
88
89             var lastWidth, lastHeight;
90
91             var reset = function() {
92                 expandChild.style.width = expand.offsetWidth + 10 + 'px';
93                 expandChild.style.height = expand.offsetHeight + 10 + 'px';
94                 expand.scrollLeft = expand.scrollWidth;
95                 expand.scrollTop = expand.scrollHeight;
96                 shrink.scrollLeft = shrink.scrollWidth;
97                 shrink.scrollTop = shrink.scrollHeight;
98                 lastWidth = element.offsetWidth;
99                 lastHeight = element.offsetHeight;
100             };
101
102             reset();
103
104             var changed = function() {
105                 if (element.resizedAttached) {
106                     element.resizedAttached.call();
107                 }
108             };
109
110             var addEvent = function(el, name, cb) {
111                 if (el.attachEvent) {
112                     el.attachEvent('on' + name, cb);
113                 } else {
114                     el.addEventListener(name, cb);
115                 }
116             };
117             
118             var onScroll = function() {
119               if (element.offsetWidth != lastWidth || element.offsetHeight != lastHeight) {
120                   changed();
121               }
122               reset();
123             }
124
125             addEvent(expand, 'scroll', onScroll);
126             addEvent(shrink, 'scroll', onScroll);
127         }
128
129         var elementType = Object.prototype.toString.call(element);
130         var isCollectionTyped = ('[object Array]' === elementType
131             || ('[object NodeList]' === elementType)
132             || ('[object HTMLCollection]' === elementType)
133             || ('undefined' !== typeof jQuery && element instanceof jQuery) //jquery
134             || ('undefined' !== typeof Elements && element instanceof Elements) //mootools
135         );
136
137         if (isCollectionTyped) {
138             var i = 0, j = element.length;
139             for (; i < j; i++) {
140                 attachResizeEvent(element[i], callback);
141             }
142         } else {
143             attachResizeEvent(element, callback);
144         }
145
146         this.detach = function() {
147             if (isCollectionTyped) {
148                 var i = 0, j = element.length;
149                 for (; i < j; i++) {
150                     ResizeSensor.detach(element[i]);
151                 }
152             } else {
153                 ResizeSensor.detach(element);
154             }
155         };
156     };
157
158     this.ResizeSensor.detach = function(element) {
159         if (element.resizeSensor) {
160             element.removeChild(element.resizeSensor);
161             delete element.resizeSensor;
162             delete element.resizedAttached;
163         }
164     };
165
166 })();