Built motion from commit b598105.|2.0.7
[motion2.git] / public / bower_components / javascript-detect-element-resize / detect-element-resize.js
1 /**
2 * Detect Element Resize
3 *
4 * https://github.com/sdecima/javascript-detect-element-resize
5 * Sebastian Decima
6 *
7 * version: 0.5.3
8 **/
9
10 (function () {
11         var attachEvent = document.attachEvent,
12                 stylesCreated = false;
13         
14         if (!attachEvent) {
15                 var requestFrame = (function(){
16                         var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
17                                                                 function(fn){ return window.setTimeout(fn, 20); };
18                         return function(fn){ return raf(fn); };
19                 })();
20                 
21                 var cancelFrame = (function(){
22                         var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
23                                                                    window.clearTimeout;
24                   return function(id){ return cancel(id); };
25                 })();
26
27                 function resetTriggers(element){
28                         var triggers = element.__resizeTriggers__,
29                                 expand = triggers.firstElementChild,
30                                 contract = triggers.lastElementChild,
31                                 expandChild = expand.firstElementChild;
32                         contract.scrollLeft = contract.scrollWidth;
33                         contract.scrollTop = contract.scrollHeight;
34                         expandChild.style.width = expand.offsetWidth + 1 + 'px';
35                         expandChild.style.height = expand.offsetHeight + 1 + 'px';
36                         expand.scrollLeft = expand.scrollWidth;
37                         expand.scrollTop = expand.scrollHeight;
38                 };
39
40                 function checkTriggers(element){
41                         return element.offsetWidth != element.__resizeLast__.width ||
42                                                  element.offsetHeight != element.__resizeLast__.height;
43                 }
44                 
45                 function scrollListener(e){
46                         var element = this;
47                         resetTriggers(this);
48                         if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
49                         this.__resizeRAF__ = requestFrame(function(){
50                                 if (checkTriggers(element)) {
51                                         element.__resizeLast__.width = element.offsetWidth;
52                                         element.__resizeLast__.height = element.offsetHeight;
53                                         element.__resizeListeners__.forEach(function(fn){
54                                                 fn.call(element, e);
55                                         });
56                                 }
57                         });
58                 };
59                 
60                 /* Detect CSS Animations support to detect element display/re-attach */
61                 var animation = false,
62                         animationstring = 'animation',
63                         keyframeprefix = '',
64                         animationstartevent = 'animationstart',
65                         domPrefixes = 'Webkit Moz O ms'.split(' '),
66                         startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
67                         pfx  = '';
68                 {
69                         var elm = document.createElement('fakeelement');
70                         if( elm.style.animationName !== undefined ) { animation = true; }    
71                         
72                         if( animation === false ) {
73                                 for( var i = 0; i < domPrefixes.length; i++ ) {
74                                         if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
75                                                 pfx = domPrefixes[ i ];
76                                                 animationstring = pfx + 'Animation';
77                                                 keyframeprefix = '-' + pfx.toLowerCase() + '-';
78                                                 animationstartevent = startEvents[ i ];
79                                                 animation = true;
80                                                 break;
81                                         }
82                                 }
83                         }
84                 }
85                 
86                 var animationName = 'resizeanim';
87                 var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
88                 var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
89         }
90         
91         function createStyles() {
92                 if (!stylesCreated) {
93                         //opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
94                         var css = (animationKeyframes ? animationKeyframes : '') +
95                                         '.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
96                                         '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
97                                 head = document.head || document.getElementsByTagName('head')[0],
98                                 style = document.createElement('style');
99                         
100                         style.type = 'text/css';
101                         if (style.styleSheet) {
102                                 style.styleSheet.cssText = css;
103                         } else {
104                                 style.appendChild(document.createTextNode(css));
105                         }
106
107                         head.appendChild(style);
108                         stylesCreated = true;
109                 }
110         }
111         
112         window.addResizeListener = function(element, fn){
113                 if (attachEvent) element.attachEvent('onresize', fn);
114                 else {
115                         if (!element.__resizeTriggers__) {
116                                 if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
117                                 createStyles();
118                                 element.__resizeLast__ = {};
119                                 element.__resizeListeners__ = [];
120                                 (element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
121                                 element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
122                                                                                                                                                                                 '<div class="contract-trigger"></div>';
123                                 element.appendChild(element.__resizeTriggers__);
124                                 resetTriggers(element);
125                                 element.addEventListener('scroll', scrollListener, true);
126                                 
127                                 /* Listen for a css animation to detect element display/re-attach */
128                                 animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
129                                         if(e.animationName == animationName)
130                                                 resetTriggers(element);
131                                 });
132                         }
133                         element.__resizeListeners__.push(fn);
134                 }
135         };
136         
137         window.removeResizeListener = function(element, fn){
138                 if (attachEvent) element.detachEvent('onresize', fn);
139                 else {
140                         element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
141                         if (!element.__resizeListeners__.length) {
142                                         element.removeEventListener('scroll', scrollListener);
143                                         element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
144                         }
145                 }
146         }
147 })();