fixing one typo and making string formatting consistent.
[oweals/karmaworld.git] / karmaworld / assets / js / jquery-scrollto.js
1 /*global define:false require:false */
2 (function (name, context, definition) {
3         if (typeof module != 'undefined' && module.exports) module.exports = definition();
4         else if (typeof define == 'function' && define.amd) define(definition);
5         else context[name] = definition();
6 })('jquery-scrollto', this, function(){
7         // Prepare
8         var jQuery, $, ScrollTo;
9         jQuery = $ = window.jQuery || require('jquery');
10
11         // Fix scrolling animations on html/body on safari
12         $.propHooks.scrollTop = $.propHooks.scrollLeft = {
13                 get: function(elem,prop) {
14                         var result = null;
15                         if ( elem.tagName === 'HTML' || elem.tagName === 'BODY' ) {
16                                 if ( prop === 'scrollLeft' ) {
17                                         result = window.scrollX;
18                                 } else if ( prop === 'scrollTop' ) {
19                                         result = window.scrollY;
20                                 }
21                         }
22                         if ( result == null ) {
23                                 result = elem[prop];
24                         }
25                         return result;
26                 }
27         };
28         $.Tween.propHooks.scrollTop = $.Tween.propHooks.scrollLeft = {
29                 get: function(tween) {
30                         return $.propHooks.scrollTop.get(tween.elem, tween.prop);
31                 },
32                 set: function(tween) {
33                         // Our safari fix
34                         if ( tween.elem.tagName === 'HTML' || tween.elem.tagName === 'BODY' ) {
35                                 // Defaults
36                                 tween.options.bodyScrollLeft = (tween.options.bodyScrollLeft || window.scrollX);
37                                 tween.options.bodyScrollTop = (tween.options.bodyScrollTop || window.scrollY);
38
39                                 // Apply
40                                 if ( tween.prop === 'scrollLeft' ) {
41                                         tween.options.bodyScrollLeft = Math.round(tween.now);
42                                 }
43                                 else if ( tween.prop === 'scrollTop' ) {
44                                         tween.options.bodyScrollTop = Math.round(tween.now);
45                                 }
46
47                                 // Apply
48                                 window.scrollTo(tween.options.bodyScrollLeft, tween.options.bodyScrollTop);
49                         }
50                         // jQuery's IE8 Fix
51                         else if ( tween.elem.nodeType && tween.elem.parentNode ) {
52                                 tween.elem[ tween.prop ] = tween.now;
53                         }
54                 }
55         };
56
57         // jQuery ScrollTo
58         ScrollTo = {
59                 // Configuration
60                 config: {
61                         duration: 400,
62                         easing: 'swing',
63                         callback: undefined,
64                         durationMode: 'each',
65                         offsetTop: 0,
66                         offsetLeft: 0
67                 },
68
69                 // Set Configuration
70                 configure: function(options){
71                         // Apply Options to Config
72                         $.extend(ScrollTo.config, options||{});
73
74                         // Chain
75                         return this;
76                 },
77
78                 // Perform the Scroll Animation for the Collections
79                 // We use $inline here, so we can determine the actual offset start for each overflow:scroll item
80                 // Each collection is for each overflow:scroll item
81                 scroll: function(collections, config){
82                         // Prepare
83                         var collection, $container, container, $target, $inline, position, containerTagName,
84                                 containerScrollTop, containerScrollLeft,
85                                 containerScrollTopEnd, containerScrollLeftEnd,
86                                 startOffsetTop, targetOffsetTop, targetOffsetTopAdjusted,
87                                 startOffsetLeft, targetOffsetLeft, targetOffsetLeftAdjusted,
88                                 scrollOptions,
89                                 callback;
90
91                         // Determine the Scroll
92                         collection = collections.pop();
93                         $container = collection.$container;
94                         $target = collection.$target;
95                         containerTagName = $container.prop('tagName');
96
97                         // Prepare the Inline Element of the Container
98                         $inline = $('<span/>').css({
99                                 'position': 'absolute',
100                                 'top': '0px',
101                                 'left': '0px'
102                         });
103                         position = $container.css('position');
104
105                         // Insert the Inline Element of the Container
106                         $container.css({position:'relative'});
107                         $inline.appendTo($container);
108
109                         // Determine the top offset
110                         startOffsetTop = $inline.offset().top;
111                         targetOffsetTop = $target.offset().top;
112                         targetOffsetTopAdjusted = targetOffsetTop - startOffsetTop - parseInt(config.offsetTop,10);
113
114                         // Determine the left offset
115                         startOffsetLeft = $inline.offset().left;
116                         targetOffsetLeft = $target.offset().left;
117                         targetOffsetLeftAdjusted = targetOffsetLeft - startOffsetLeft - parseInt(config.offsetLeft,10);
118
119                         // Determine current scroll positions
120                         containerScrollTop = $container.prop('scrollTop');
121                         containerScrollLeft = $container.prop('scrollLeft');
122
123                         // Reset the Inline Element of the Container
124                         $inline.remove();
125                         $container.css({position:position});
126
127                         // Prepare the scroll options
128                         scrollOptions = {};
129
130                         // Prepare the callback
131                         callback = function(event){
132                                 // Check
133                                 if ( collections.length === 0 ) {
134                                         // Callback
135                                         if ( typeof config.callback === 'function' ) {
136                                                 config.callback();
137                                         }
138                                 }
139                                 else {
140                                         // Recurse
141                                         ScrollTo.scroll(collections,config);
142                                 }
143                                 // Return true
144                                 return true;
145                         };
146
147                         // Handle if we only want to scroll if we are outside the viewport
148                         if ( config.onlyIfOutside ) {
149                                 // Determine current scroll positions
150                                 containerScrollTopEnd = containerScrollTop + $container.height();
151                                 containerScrollLeftEnd = containerScrollLeft + $container.width();
152
153                                 // Check if we are in the range of the visible area of the container
154                                 if ( containerScrollTop < targetOffsetTopAdjusted && targetOffsetTopAdjusted < containerScrollTopEnd ) {
155                                         targetOffsetTopAdjusted = containerScrollTop;
156                                 }
157                                 if ( containerScrollLeft < targetOffsetLeftAdjusted && targetOffsetLeftAdjusted < containerScrollLeftEnd ) {
158                                         targetOffsetLeftAdjusted = containerScrollLeft;
159                                 }
160                         }
161
162                         // Determine the scroll options
163                         if ( targetOffsetTopAdjusted !== containerScrollTop ) {
164                                 scrollOptions.scrollTop = targetOffsetTopAdjusted;
165                         }
166                         if ( targetOffsetLeftAdjusted !== containerScrollLeft ) {
167                                 scrollOptions.scrollLeft = targetOffsetLeftAdjusted;
168                         }
169
170                         // Check to see if the scroll is necessary
171                         if ( $container.prop('scrollHeight') === $container.width() ) {
172                                 delete scrollOptions.scrollTop;
173                         }
174                         if ( $container.prop('scrollWidth') === $container.width() ) {
175                                 delete scrollOptions.scrollLeft;
176                         }
177
178                         // Perform the scroll
179                         if ( scrollOptions.scrollTop != null || scrollOptions.scrollLeft != null ) {
180                                 $container.animate(scrollOptions, {
181                                         duration: config.duration,
182                                         easing: config.easing,
183                                         complete: callback
184                                 });
185                         }
186                         else {
187                                 callback();
188                         }
189
190                         // Return true
191                         return true;
192                 },
193
194                 // ScrollTo the Element using the Options
195                 fn: function(options){
196                         // Prepare
197                         var collections, config, $container, container;
198                         collections = [];
199
200                         // Prepare
201                         var     $target = $(this);
202                         if ( $target.length === 0 ) {
203                                 // Chain
204                                 return this;
205                         }
206
207                         // Handle Options
208                         config = $.extend({},ScrollTo.config,options);
209
210                         // Fetch
211                         $container = $target.parent();
212                         container = $container.get(0);
213
214                         // Cycle through the containers
215                         while ( ($container.length === 1) && (container !== document.body) && (container !== document) ) {
216                                 // Check Container for scroll differences
217                                 var containerScrollTop, containerScrollLeft;
218                                 containerScrollTop = $container.css('overflow-y') !== 'visible' && container.scrollHeight !== container.clientHeight;
219                                 containerScrollLeft =  $container.css('overflow-x') !== 'visible' && container.scrollWidth !== container.clientWidth;
220                                 if ( containerScrollTop || containerScrollLeft ) {
221                                         // Push the Collection
222                                         collections.push({
223                                                 '$container': $container,
224                                                 '$target': $target
225                                         });
226                                         // Update the Target
227                                         $target = $container;
228                                 }
229                                 // Update the Container
230                                 $container = $container.parent();
231                                 container = $container.get(0);
232                         }
233
234                         // Add the final collection
235                         collections.push({
236                                 '$container': $('html'),
237                                 // document.body doesn't work in firefox, html works for all
238                                 // internet explorer starts at the beggining
239                                 '$target': $target
240                         });
241
242                         // Adjust the Config
243                         if ( config.durationMode === 'all' ) {
244                                 config.duration /= collections.length;
245                         }
246
247                         // Handle
248                         ScrollTo.scroll(collections,config);
249
250                         // Chain
251                         return this;
252                 }
253         };
254
255         // Apply our extensions to jQuery
256         $.ScrollTo = $.ScrollTo || ScrollTo;
257         $.fn.ScrollTo = $.fn.ScrollTo || ScrollTo.fn;
258
259         // Export
260         return ScrollTo;
261 });