1/* 2Copyright (c) 2009 Victor Stanciu - https://www.victorstanciu.ro 3 4Permission is hereby granted, free of charge, to any person 5obtaining a copy of this software and associated documentation 6files (the "Software"), to deal in the Software without 7restriction, including without limitation the rights to use, 8copy, modify, merge, publish, distribute, sublicense, and/or sell 9copies of the Software, and to permit persons to whom the 10Software is furnished to do so, subject to the following 11conditions: 12 13The above copyright notice and this permission notice shall be 14included in all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23OTHER DEALINGS IN THE SOFTWARE. 24*/ 25 26Carousel = Class.create(Abstract, { 27 initialize: function (scroller, slides, controls, options) { 28 this.scrolling = false; 29 this.scroller = $(scroller); 30 this.slides = slides; 31 this.controls = controls; 32 33 this.options = Object.extend({ 34 duration: 1, 35 auto: false, 36 frequency: 3, 37 visibleSlides: 1, 38 controlClassName: 'carousel-control', 39 jumperClassName: 'carousel-jumper', 40 disabledClassName: 'carousel-disabled', 41 selectedClassName: 'carousel-selected', 42 circular: false, 43 wheel: true, 44 effect: 'scroll', 45 transition: 'sinoidal' 46 }, options || {}); 47 48 if (this.options.effect == 'fade') { 49 this.options.circular = true; 50 } 51 52 this.slides.each(function(slide, index) { 53 slide._index = index; 54 }); 55 56 if (this.controls) { 57 this.controls.invoke('observe', 'click', this.click.bind(this)); 58 } 59 60 if (this.options.wheel) { 61 this.scroller.observe('mousewheel', this.wheel.bindAsEventListener(this)).observe('DOMMouseScroll', this.wheel.bindAsEventListener(this));; 62 } 63 64 if (this.options.auto) { 65 this.start(); 66 } 67 68 if (this.options.initial) { 69 var initialIndex = this.slides.indexOf($(this.options.initial)); 70 if (initialIndex > (this.options.visibleSlides - 1) && this.options.visibleSlides > 1) { 71 if (initialIndex > this.slides.length - (this.options.visibleSlides + 1)) { 72 initialIndex = this.slides.length - this.options.visibleSlides; 73 } 74 } 75 this.moveTo(this.slides[initialIndex]); 76 } 77 }, 78 79 click: function (event) { 80 this.stop(); 81 82 var element = event.findElement('a'); 83 84 if (!element.hasClassName(this.options.disabledClassName)) { 85 if (element.hasClassName(this.options.controlClassName)) { 86 eval("this." + element.rel + "()"); 87 } else if (element.hasClassName(this.options.jumperClassName)) { 88 this.moveTo(element.rel); 89 if (this.options.selectedClassName) { 90 this.controls.invoke('removeClassName', this.options.selectedClassName); 91 element.addClassName(this.options.selectedClassName); 92 } 93 } 94 } 95 96 this.deactivateControls(); 97 98 event.stop(); 99 }, 100 101 moveTo: function (element) { 102 if (this.options.beforeMove && (typeof this.options.beforeMove == 'function')) { 103 this.options.beforeMove(); 104 } 105 106 this.previous = this.current ? this.current : this.slides[0]; 107 this.current = $(element); 108 109 var scrollerOffset = this.scroller.cumulativeOffset(); 110 var elementOffset = this.current.cumulativeOffset(); 111 112 if (this.scrolling) { 113 this.scrolling.cancel(); 114 } 115 116 switch (this.options.effect) { 117 case 'fade': 118 this.scrolling = new Effect.Opacity(this.scroller, { 119 from: 1.0, 120 to: 0, 121 duration: this.options.duration, 122 afterFinish: (function () { 123 this.scroller.scrollLeft = elementOffset[0] - scrollerOffset[0]; 124 this.scroller.scrollTop = elementOffset[1] - scrollerOffset[1]; 125 126 new Effect.Opacity(this.scroller, { 127 from: 0, 128 to: 1.0, 129 duration: this.options.duration, 130 afterFinish: (function () { 131 if (this.controls) { 132 this.activateControls(); 133 } 134 if (this.options.afterMove && (typeof this.options.afterMove == 'function')) { 135 this.options.afterMove(); 136 } 137 }).bind(this) 138 }); 139 } 140 ).bind(this)}); 141 break; 142 case 'scroll': 143 default: 144 var transition; 145 switch (this.options.transition) { 146 case 'spring': 147 transition = Effect.Transitions.spring; 148 break; 149 case 'sinoidal': 150 default: 151 transition = Effect.Transitions.sinoidal; 152 break; 153 } 154 155 this.scrolling = new Effect.SmoothScroll(this.scroller, { 156 duration: this.options.duration, 157 x: (elementOffset[0] - scrollerOffset[0]), 158 y: (elementOffset[1] - scrollerOffset[1]), 159 transition: transition, 160 afterFinish: (function () { 161 if (this.controls) { 162 this.activateControls(); 163 } 164 if (this.options.afterMove && (typeof this.options.afterMove == 'function')) { 165 this.options.afterMove(); 166 } 167 this.scrolling = false;
168 }).bind(this)}); 169 break; 170 } 171 172 return false; 173 }, 174 175 prev: function () { 176 if (this.current) { 177 var currentIndex = this.current._index; 178 var prevIndex = (currentIndex == 0) ? (this.options.circular ? this.slides.length - 1 : 0) : currentIndex - 1; 179 } else { 180 var prevIndex = (this.options.circular ? this.slides.length - 1 : 0); 181 } 182 183 if (prevIndex == (this.slides.length - 1) && this.options.circular && this.options.effect != 'fade') { 184 this.scroller.scrollLeft = (this.slides.length - 1) * this.slides.first().getWidth(); 185 this.scroller.scrollTop = (this.slides.length - 1) * this.slides.first().getHeight(); 186 prevIndex = this.slides.length - 2; 187 } 188 189 this.moveTo(this.slides[prevIndex]); 190 }, 191 192 next: function () { 193 if (this.current) { 194 var currentIndex = this.current._index; 195 var nextIndex = (this.slides.length - 1 == currentIndex) ? (this.options.circular ? 0 : currentIndex) : currentIndex + 1; 196 } else { 197 var nextIndex = 1; 198 } 199 200 if (nextIndex == 0 && this.options.circular && this.options.effect != 'fade') { 201 this.scroller.scrollLeft = 0; 202 this.scroller.scrollTop = 0; 203 nextIndex = 1; 204 } 205 206 if (nextIndex > this.slides.length - (this.options.visibleSlides + 1)) { 207 nextIndex = this.slides.length - this.options.visibleSlides; 208 } 209 210 this.moveTo(this.slides[nextIndex]); 211 }, 212 213 first: function () { 214 this.moveTo(this.slides[0]); 215 }, 216 217 last: function () { 218 this.moveTo(this.slides[this.slides.length - 1]); 219 }, 220 221 toggle: function () { 222 if (this.previous) { 223 this.moveTo(this.slides[this.previous._index]); 224 } else { 225 return false; 226 } 227 }, 228 229 stop: function () { 230 if (this.timer) { 231 clearTimeout(this.timer); 232 } 233 }, 234 235 start: function () { 236 this.periodicallyUpdate(); 237 }, 238 239 pause: function () { 240 this.stop(); 241 this.activateControls(); 242 }, 243 244 resume: function (event) { 245 if (event) { 246 var related = event.relatedTarget || event.toElement; 247 if (!related || (!this.slides.include(related) && !this.slides.any(function (slide) { return related.descendantOf(slide); }))) { 248 this.start(); 249 } 250 } else { 251 this.start(); 252 } 253 }, 254 255 periodicallyUpdate: function () { 256 if (this.timer != null) { 257 clearTimeout(this.timer); 258 this.next(); 259 } 260 this.timer = setTimeout(this.periodicallyUpdate.bind(this), this.options.frequency * 1000); 261 }, 262 263 wheel: function (event) { 264 event.cancelBubble = true; 265 event.stop(); 266 267 var delta = 0; 268 if (!event) { 269 event = window.event; 270 } 271 if (event.wheelDelta) { 272 delta = event.wheelDelta / 120; 273 } else if (event.detail) { 274 delta = -event.detail / 3; 275 } 276 277 if (!this.scrolling) { 278 this.deactivateControls(); 279 if (delta > 0) { 280 this.prev(); 281 } else { 282 this.next(); 283 } 284 } 285 286 return Math.round(delta); //Safari Round 287 }, 288 289 deactivateControls: function () { 290 this.controls.invoke('addClassName', this.options.disabledClassName); 291 }, 292 293 activateControls: function () { 294 this.controls.invoke('removeClassName', this.options.disabledClassName); 295 } 296}); 297 298 299Effect.SmoothScroll = Class.create(); 300Object.extend(Object.extend(Effect.SmoothScroll.prototype, Effect.Base.prototype), { 301 initialize: function (element) { 302 this.element = $(element); 303 var options = Object.extend({ x: 0, y: 0, mode: 'absolute' } , arguments[1] || {}); 304 this.start(options); 305 }, 306 307 setup: function () { 308 if (this.options.continuous && !this.element._ext) { 309 this.element.cleanWhitespace(); 310 this.element._ext = true; 311 this.element.appendChild(this.element.firstChild); 312 } 313 314 this.originalLeft = this.element.scrollLeft; 315 this.originalTop = this.element.scrollTop; 316 317 if (this.options.mode == 'absolute') { 318 this.options.x -= this.originalLeft; 319 this.options.y -= this.originalTop; 320 } 321 }, 322 323 update: function (position) { 324 this.element.scrollLeft = this.options.x * position + this.originalLeft; 325 this.element.scrollTop = this.options.y * position + this.originalTop; 326 } 327});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.