vendor: 11,792 bytes, lines 1-436
1/* 2SmoothScroll v0.9.9 3Licensed under the terms of the MIT license. 4 5People involved 6- Balazs Galambosi: maintainer (CHANGELOG.txt) 7- Patrick Brunner ([email protected]) 8- Michael Herf: ssc_pulse Algorithm 9*/ 10 11jQuery(document).ready(function($){ 12 13// Scroll Variables (tweakable) 14var ssc_framerate = 50; //150 [Hz] 15var ssc_animtime = 400; //600 [px] 16var ssc_stepsize = 120; //170 [px] 17 18// ssc_pulse (less tweakable) 19// ratio of "tail" to "acceleration" 20var ssc_pulseAlgorithm = true; 21var ssc_pulseScale = 6; 22var ssc_pulseNormalize = 1; 23 24// Keyboard Settings 25var ssc_keyboardsupport = true; 26var ssc_arrowscroll = 60; // [px] 27 28// Other Variables 29var ssc_frame = false; 30var ssc_direction = { x: 0, y: 0 }; 31var ssc_initdone = false; 32var ssc_fixedback = true; 33var ssc_root = document.documentElement; 34var ssc_activeElement; 35 36var ssc_key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36 }; 37 38/*********************************************** 39 * INITIALIZE 40 ***********************************************/ 41 42/** 43 * Sets up scrolls array, determines if ssc_frames are involved. 44 */ 45function ssc_init() { 46 47 if (!document.body) return; 48 49 var body = document.body; 50 var html = document.documentElement; 51 var windowHeight = window.innerHeight; 52 var scrollHeight = body.scrollHeight; 53 54 // check compat mode for ssc_root element 55 ssc_root = (document.compatMode.indexOf('CSS') >= 0) ? html : body; 56 ssc_activeElement = body; 57 58 ssc_initdone = true; 59 60 // Checks if this script is running in a ssc_frame 61 if (top != self) { 62 ssc_frame = true; 63 } 64 65 /** 66 * This fixes a bug where the areas left and right to 67 * the content does not trigger the onmousewheel event 68 * on some pages. e.g.: html, body { height: 100% } 69 */ 70 else if (scrollHeight > windowHeight && 71 (body.offsetHeight <= windowHeight || 72 html.offsetHeight <= windowHeight)) { 73 ssc_root.style.height = "auto"; 74 if (ssc_root.offsetHeight <= windowHeight) { 75 var underlay = document.createElement("div"); 76 underlay.style.clear = "both"; 77 body.appendChild(underlay); 78 } 79 } 80 81 if (!ssc_fixedback) { 82 body.style.backgroundAttachment = "scroll"; 83 html.style.backgroundAttachment = "scroll"; 84 } 85 86 if (ssc_keyboardsupport) { 87 ssc_addEvent("keydown", ssc_keydown); 88 } 89} 90 91 92/************************************************ 93 * SCROLLING 94 ************************************************/ 95 96var ssc_que = []; 97var ssc_pending = false; 98 99/** 100 * Pushes scroll actions to the scrolling queue. 101 */ 102function ssc_scrollArray(elem, left, top, delay) { 103 104 delay || (delay = 1000); 105 ssc_directionCheck(left, top); 106 107 // push a scroll command 108 ssc_que.push({ 109 x: left, 110 y: top, 111 lastX: (left < 0) ? 0.99 : -0.99, 112 lastY: (top < 0) ? 0.99 : -0.99, 113 start: +new Date 114 }); 115 116 // don't act if there's a ssc_pending queue 117 if (ssc_pending) { 118 return; 119 } 120 121 var step = function() { 122 123 var now = +new Date; 124 var scrollX = 0; 125 var scrollY = 0; 126 127 for (var i = 0; i < ssc_que.length; i++) { 128 129 var item = ssc_que[i]; 130 var elapsed = now - item.start; 131 var finished = (elapsed >= ssc_animtime); 132 133 // scroll position: [0, 1] 134 var position = (finished) ? 1 : elapsed / ssc_animtime; 135 136 // easing [optional] 137 if (ssc_pulseAlgorithm) { 138 position = ssc_pulse(position); 139 } 140 141 // only need the difference 142 var x = (item.x * position - item.lastX) >> 0; 143 var y = (item.y * position - item.lastY) >> 0; 144 145 // add this to the total scrolling 146 scrollX += x; 147 scrollY += y; 148 149 // update last values 150 item.lastX += x; 151 item.lastY += y; 152 153 // delete and step back if it's over 154 if (finished) { 155 ssc_que.splice(i, 1); i--; 156 } 157 } 158 159 // scroll left 160 if (left) { 161 var lastLeft = elem.scrollLeft; 162 elem.scrollLeft += scrollX; 163 164 // scroll left failed (edge) 165 if (scrollX && elem.scrollLeft === lastLeft) { 166 left = 0; 167 } 168 } 169 170 // scroll top 171 if (top) { 172 var lastTop = elem.scrollTop; 173 elem.scrollTop += scrollY; 174 175 // scroll top failed (edge) 176 if (scrollY && elem.scrollTop === lastTop) { 177 top = 0; 178 } 179 } 180 181 // clean up if there's nothing left to do 182 if (!left && !top) { 183 ssc_que = []; 184 } 185 186 if (ssc_que.length) { 187 setTimeout(step, delay / ssc_framerate + 1); 188 } else { 189 ssc_pending = false; 190 } 191 } 192 193 // start a new queue of actions 194 setTimeout(step, 0); 195 ssc_pending = true; 196} 197 198 199/*********************************************** 200 * EVENTS 201 ***********************************************/ 202 203/** 204 * Mouse ssc_wheel handler. 205 * @param {Object} event 206 */ 207function ssc_wheel(event) { 208 209 if (!ssc_initdone) { 210 ssc_init(); 211 } 212 213 var target = event.target; 214 var overflowing = ssc_overflowingAncestor(target); 215 216 // use default if there's no overflowing 217 // element or default action is prevented 218 if (!overflowing || event.defaultPrevented || 219 ssc_isNodeName(ssc_activeElement, "embed") || 220 (ssc_isNodeName(target, "embed") && /\.pdf/i.test(target.src))) { 221 return true; 222 } 223 224 var deltaX = event.wheelDeltaX || 0; 225 var deltaY = event.wheelDeltaY || 0; 226 227 // use wheelDelta if deltaX/Y is not available 228 if (!deltaX && !deltaY) { 229 deltaY = event.wheelDelta || 0; 230 } 231 232 // scale by step size 233 // delta is 120 most of the time 234 // synaptics seems to send 1 sometimes 235 if (Math.abs(deltaX) > 1.2) { 236 deltaX *= ssc_stepsize / 120; 237 } 238 if (Math.abs(deltaY) > 1.2) { 239 deltaY *= ssc_stepsize / 120; 240 } 241 242 ssc_scrollArray(overflowing, -deltaX, -deltaY); 243 event.preventDefault(); 244} 245 246/** 247 * ssc_keydown event handler. 248 * @param {Object} event 249 */ 250function ssc_keydown(event) { 251 252 var target = event.target; 253 var modifier = event.ctrlKey || event.altKey || event.metaKey; 254 255 // do nothing if user is editing text 256 // or using a modifier ssc_key (except shift) 257 if ( /input|textarea|embed/i.test(target.nodeName) || 258 target.isContentEditable || 259 event.defaultPrevented || 260 modifier ) { 261 return true; 262 } 263 // spacebar should trigger button press 264 if (ssc_isNodeName(target, "button") && 265 event.keyCode === ssc_key.spacebar) { 266 return true; 267 } 268 269 var shift, x = 0, y = 0; 270 var elem = ssc_overflowingAncestor(ssc_activeElement); 271 var clientHeight = elem.clientHeight; 272 273 if (elem == document.body) { 274 clientHeight = window.innerHeight; 275 } 276 277 switch (event.keyCode) { 278 case ssc_key.up: 279 y = -ssc_arrowscroll; 280 break; 281 case ssc_key.down: 282 y = ssc_arrowscroll; 283 break; 284 case ssc_key.spacebar: // (+ shift) 285 shift = event.shiftKey ? 1 : -1; 286 y = -shift * clientHeight * 0.9; 287 break; 288 case ssc_key.pageup: 289 y = -clientHeight * 0.9; 290 break; 291 case ssc_key.pagedown: 292 y = clientHeight * 0.9; 293 break; 294 case ssc_key.home: 295 y = -elem.scrollTop; 296 break; 297 case ssc_key.end: 298 var damt = elem.scrollHeight - elem.scrollTop - clientHeight; 299 y = (damt > 0) ? damt+10 : 0; 300 break; 301 case ssc_key.left: 302 x = -ssc_arrowscroll; 303 break; 304 case ssc_key.right: 305 x = ssc_arrowscroll; 306 break; 307 default: 308 return true; // a ssc_key we don't care about 309 } 310 311 ssc_scrollArray(elem, x, y); 312 event.preventDefault(); 313} 314 315/** 316 * ssc_mousedown event only for updating ssc_activeElement 317 */ 318function ssc_mousedown(event) { 319 ssc_activeElement = event.target; 320} 321 322 323/*********************************************** 324 * OVERFLOW 325 ***********************************************/ 326 327var ssc_cache = {}; // cleared out every once in while 328setInterval(function(){ ssc_cache = {}; }, 10 * 1000); 329 330var ssc_uniqueID = (function() { 331 var i = 0; 332 return function (el) { 333 return el.ssc_uniqueID || (el.ssc_uniqueID = i++); 334 }; 335})(); 336 337function ssc_setCache(elems, overflowing) { 338 for (var i = elems.length; i--;) 339 ssc_cache[ssc_uniqueID(elems[i])] = overflowing; 340 return overflowing; 341} 342 343function ssc_overflowingAncestor(el) { 344 var elems = []; 345 var ssc_rootScrollHeight = ssc_root.scrollHeight; 346 do { 347 var cached = ssc_cache[ssc_uniqueID(el)]; 348 if (cached) { 349 return ssc_setCache(elems, cached); 350 } 351 elems.push(el); 352 if (ssc_rootScrollHeight === el.scrollHeight) { 353 if (!ssc_frame || ssc_root.clientHeight + 10 < ssc_rootScrollHeight) { 354 return ssc_setCache(elems, document.body); // scrolling ssc_root in WebKit 355 } 356 } else if (el.clientHeight + 10 < el.scrollHeight) { 357 overflow = getComputedStyle(el, "").getPropertyValue("overflow"); 358 if (overflow === "scroll" || overflow === "auto") { 359 return ssc_setCache(elems, el); 360 } 361 } 362 } while (el = el.parentNode); 363} 364 365 366/*********************************************** 367 * HELPERS 368 ***********************************************/ 369 370function ssc_addEvent(type, fn, bubble) { 371 window.addEventListener(type, fn, (bubble||false)); 372} 373 374function ssc_removeEvent(type, fn, bubble) { 375 window.removeEventListener(type, fn, (bubble||false)); 376} 377 378function ssc_isNodeName(el, tag) { 379 return el.nodeName.toLowerCase() === tag.toLowerCase(); 380} 381 382function ssc_directionCheck(x, y) { 383 x = (x > 0) ? 1 : -1; 384 y = (y > 0) ? 1 : -1; 385 if (ssc_direction.x !== x || ssc_direction.y !== y) { 386 ssc_direction.x = x; 387 ssc_direction.y = y; 388 ssc_que = []; 389 } 390} 391 392 393/*********************************************** 394 * ssc_pulse 395 ***********************************************/ 396 397/** 398 * Viscous fluid with a ssc_pulse for part and decay for the rest. 399 * - Applies a fixed force over an interval (a damped acceleration), and 400 * - Lets the exponential bleed away the velocity over a longer interval 401 * - Michael Herf, http://stereopsis.com/stopping/ 402 */ 403function ssc_pulse_(x) { 404 var val, start, expx; 405 // test 406 x = x * ssc_pulseScale; 407 if (x < 1) { // acceleartion 408 val = x - (1 - Math.exp(-x)); 409 } else { // tail 410 // the previous animation ended here: 411 start = Math.exp(-1); 412 // simple viscous drag 413 x -= 1; 414 expx = 1 - Math.exp(-x); 415 val = start + (expx * (1 - start)); 416 } 417 return val * ssc_pulseNormalize; 418} 419 420function ssc_pulse(x) { 421 if (x >= 1) return 1; 422 if (x <= 0) return 0; 423 424 if (ssc_pulseNormalize == 1) { 425 ssc_pulseNormalize /= ssc_pulse_(1); 426 } 427 return ssc_pulse_(x); 428} 429 430$.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase()); 431if ( $.browser.chrome ) { 432 ssc_addEvent("mousedown", ssc_mousedown); 433 ssc_addEvent("mousewheel", ssc_wheel); 434 ssc_addEvent("load", ssc_init); 435 } 436});
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.