1/* jquery.nicescroll 2-- version 3.6.8 3-- copyright 2016-02-29 InuYaksa*2016 4-- licensed under the MIT 5-- 6-- http://nicescroll.areaaperta.com/ 7-- https://github.com/inuyaksa/jquery.nicescroll 8-- 9*/ 10 11(function(factory) { 12 if (typeof define === 'function' && define.amd) { 13 // AMD. Register as anonymous module. 14 define(['jquery'], factory); 15 } else if (typeof exports === 'object') { 16 // Node/CommonJS. 17 module.exports = factory(require('jquery')); 18 } else { 19 // Browser globals. 20 factory(jQuery); 21 } 22}(function(jQuery) { 23 "use strict"; 24 25 // globals 26 var domfocus = false; 27 var mousefocus = false; 28 var tabindexcounter = 0; 29 var ascrailcounter = 2000; 30 var globalmaxzindex = 0; 31 32 var $ = jQuery; // sandbox 33 34 // http://stackoverflow.com/questions/2161159/get-script-path 35 function getScriptPath() { 36 var scripts = document.getElementsByTagName('script'); 37 var path = scripts.length ? scripts[scripts.length - 1].src.split('?')[0] : ''; 38 return (path.split('/').length > 0) ? path.split('/').slice(0, -1).join('/') + '/' : ''; 39 } 40 41 var vendors = ['webkit','ms','moz','o']; 42 43 var setAnimationFrame = window.requestAnimationFrame || false; 44 var clearAnimationFrame = window.cancelAnimationFrame || false; 45 46 if (!setAnimationFrame) { // legacy detection 47 for (var vx in vendors) { 48 var v = vendors[vx]; 49 setAnimationFrame = window[v + 'RequestAnimationFrame']; 50 if (setAnimationFrame) { 51 clearAnimationFrame = window[v + 'CancelAnimationFrame'] || window[v + 'CancelRequestAnimationFrame']; 52 break; 53 } 54 } 55 } 56 57 var ClsMutationObserver = window.MutationObserver || window.WebKitMutationObserver || false; 58 59 var _globaloptions = { 60 zindex: "auto", 61 cursoropacitymin: 0, 62 cursoropacitymax: 1, 63 cursorcolor: "#424242", 64 cursorwidth: "6px", 65 cursorborder: "1px solid #fff", 66 cursorborderradius: "5px", 67 scrollspeed: 60, 68 mousescrollstep: 8 * 3, 69 touchbehavior: false, 70 hwacceleration: true, 71 usetransition: true, 72 boxzoom: false, 73 dblclickzoom: true, 74 gesturezoom: true, 75 grabcursorenabled: true, 76 autohidemode: true, 77 background: "", 78 iframeautoresize: true, 79 cursorminheight: 32, 80 preservenativescrolling: true, 81 railoffset: false, 82 railhoffset: false, 83 bouncescroll: true, 84 spacebarenabled: true, 85 railpadding: { 86 top: 0, 87 right: 0, 88 left: 0, 89 bottom: 0 90 }, 91 disableoutline: true, 92 horizrailenabled: true, 93 railalign: "right", 94 railvalign: "bottom", 95 enabletranslate3d: true, 96 enablemousewheel: true, 97 enablekeyboard: true, 98 smoothscroll: true, 99 sensitiverail: true, 100 enablemouselockapi: true, 101 // cursormaxheight:false, 102 cursorfixedheight: false, 103 directionlockdeadzone: 6, 104 hidecursordelay: 400, 105 nativeparentscrolling: true, 106 enablescrollonselection: true, 107 overflowx: true, 108 overflowy: true, 109 cursordragspeed: 0.3, 110 rtlmode: "auto", 111 cursordragontouch: false, 112 oneaxismousemode: "auto", 113 scriptpath: getScriptPath(), 114 preventmultitouchscrolling: true, 115 disablemutationobserver:false 116 }; 117 118 var browserdetected = false; 119 120 var getBrowserDetection = function() { 121 122 if (browserdetected) return browserdetected; 123 124 var _el = document.createElement('DIV'), 125 _style = _el.style, 126 _agent = navigator.userAgent, 127 _platform = navigator.platform, 128 d = {}; 129 130 d.haspointerlock = "pointerLockElement" in document || "webkitPointerLockElement" in document || "mozPointerLockElement" in document; 131 132 d.isopera = ("opera" in window); // 12- 133 d.isopera12 = (d.isopera && ("getUserMedia" in navigator)); 134 d.isoperamini = (Object.prototype.toString.call(window.operamini) === "[object OperaMini]"); 135 136 d.isie = (("all" in document) && ("attachEvent" in _el) && !d.isopera); //IE10- 137 d.isieold = (d.isie && !("msInterpolationMode" in _style)); // IE6 and older 138 d.isie7 = d.isie && !d.isieold && (!("documentMode" in document) || (document.documentMode == 7)); 139 d.isie8 = d.isie && ("documentMode" in document) && (document.documentMode == 8); 140 d.isie9 = d.isie && ("performance" in window) && (document.documentMode == 9); 141 d.isie10 = d.isie && ("performance" in window) && (document.documentMode == 10); 142 d.isie11 = ("msRequestFullscreen" in _el) && (document.documentMode >= 11); // IE11+ 143 d.isieedge12 = (navigator.userAgent.match(/Edge\/12\./)); // IE Edge 12 144 d.isieedge = ("msOverflowStyle" in _el); // IE Edge 145 d.ismodernie = d.isie11 || d.isieedge; 146 147 d.isie9mobile = /iemobile.9/i.test(_agent); //wp 7.1 mango 148 if (d.isie9mobile) d.isie9 = false; 149 d.isie7mobile = (!d.isie9mobile && d.isie7) && /iemobile/i.test(_agent); //wp 7.0 150 151 d.ismozilla = ("MozAppearance" in _style); 152 153 d.iswebkit = ("WebkitAppearance" in _style); 154 155 d.ischrome = ("chrome" in window); 156 d.ischrome38 = (d.ischrome && ("touchAction" in _style)); // behavior changed in touch emulation 157 d.ischrome22 = (!d.ischrome38)&&(d.ischrome && d.haspointerlock); 158 d.ischrome26 = (!d.ischrome38)&&(d.ischrome && ("transition" in _style)); // issue with transform detection (maintain prefix) 159 160 d.cantouch = ("ontouchstart" in document.documentElement) || ("ontouchstart" in window); // with detection for Chrome Touch Emulation 161 d.hasw3ctouch = (window.PointerEvent || false) && ((navigator.MaxTouchPoints > 0)||(navigator.msMaxTouchPoints > 0)); //IE11 pointer events, following W3C Pointer Events spec 162 d.hasmstouch = (!d.hasw3ctouch)&&(window.MSPointerEvent || false); // IE10 pointer events 163 164 d.ismac = /^mac$/i.test(_platform); 165 166 d.isios = (d.cantouch && /iphone|ipad|ipod/i.test(_platform)); 167 d.isios4 = ((d.isios) && !("seal" in Object)); 168 d.isios7 = ((d.isios)&&("webkitHidden" in document)); //iOS 7+ 169 d.isios8 = ((d.isios)&&("hidden" in document)); //iOS 8+ 170 171 d.isandroid = (/android/i.test(_agent)); 172 173 d.haseventlistener = ("addEventListener" in _el); 174 175 d.trstyle = false; 176 d.hastransform = false; 177 d.hastranslate3d = false; 178 d.transitionstyle = false; 179 d.hastransition = false; 180 d.transitionend = false; 181 182 var a; 183 var check = ['transform', 'msTransform', 'webkitTransform', 'MozTransform', 'OTransform']; 184 for (a = 0; a < check.length; a++) { 185 if (_style[check[a]] !== undefined) { 186 d.trstyle = check[a]; 187 break; 188 } 189 } 190 d.hastransform = (!!d.trstyle); 191 if (d.hastransform) { 192 _style[d.trstyle] = "translate3d(1px,2px,3px)"; 193 d.hastranslate3d = /translate3d/.test(_style[d.trstyle]); 194 } 195 196 d.transitionstyle = false; 197 d.prefixstyle = ''; 198 d.transitionend = false; 199 check = ['transition', 'webkitTransition', 'msTransition', 'MozTransition', 'OTransition', 'OTransition', 'KhtmlTransition']; 200 var prefix = ['', '-webkit-', '-ms-', '-moz-', '-o-', '-o', '-khtml-']; 201 var evs = ['transitionend', 'webkitTransitionEnd', 'msTransitionEnd', 'transitionend', 'otransitionend', 'oTransitionEnd', 'KhtmlTransitionEnd']; 202 for (a = 0; a < check.length; a++) { 203 if (check[a] in _style) { 204 d.transitionstyle = check[a]; 205 d.prefixstyle = prefix[a]; 206 d.transitionend = evs[a]; 207 break; 208 } 209 } 210 if (d.ischrome26) { // always use prefix 211 d.prefixstyle = prefix[1]; 212 } 213 214 d.hastransition = (d.transitionstyle); 215 216 function detectCursorGrab() { 217 var lst = ['grab','-webkit-grab', '-moz-grab']; 218 if ((d.ischrome && !d.ischrome38) || d.isie) lst = []; // force setting for IE returns false positive and chrome cursor bug 219 for (var a = 0; a < lst.length; a++) { 220 var p = lst[a]; 221 _style.cursor = p; 222 if (_style.cursor == p) return p; 223 } 224 return 'url(//patriciaportfolio.googlecode.com/files/openhand.cur),n-resize'; // thank you google for custom cursor! 225 } 226 d.cursorgrabvalue = detectCursorGrab(); 227 228 d.hasmousecapture = ("setCapture" in _el); 229 230 d.hasMutationObserver = (ClsMutationObserver !== false); 231 232 _el = null; //memory released 233 234 browserdetected = d; 235 236 return d; 237 }; 238 239 var NiceScrollClass = function(myopt, me) { 240 241 var self = this; 242 243 this.version = '3.6.8'; 244 this.name = 'nicescroll'; 245 246 this.me = me; 247 248 this.opt = { 249 doc: $("body"), 250 win: false 251 }; 252 253 $.extend(this.opt, _globaloptions); // clone opts 254 255 // Options for internal use 256 this.opt.snapbackspeed = 80; 257 258 if (myopt || false) { 259 for (var a in self.opt) { 260 if (myopt[a] !== undefined) self.opt[a] = myopt[a]; 261 } 262 } 263 264 if (self.opt.disablemutationobserver) ClsMutationObserver = false; 265 266 this.doc = self.opt.doc; 267 this.iddoc = (this.doc && this.doc[0]) ? this.doc[0].id || '' : ''; 268 this.ispage = /^BODY|HTML/.test((self.opt.win) ? self.opt.win[0].nodeName : this.doc[0].nodeName); 269 this.haswrapper = (self.opt.win !== false); 270 this.win = self.opt.win || (this.ispage ? $(window) : this.doc);
vendor: 7,117 bytes, lines 271-508
271 this.docscroll = (this.ispage && !this.haswrapper) ? $(window) : this.win; 272 this.body = $("body"); 273 this.viewport = false; 274 275 this.isfixed = false; 276 277 this.iframe = false; 278 this.isiframe = ((this.doc[0].nodeName == 'IFRAME') && (this.win[0].nodeName == 'IFRAME')); 279 280 this.istextarea = (this.win[0].nodeName == 'TEXTAREA'); 281 282 this.forcescreen = false; //force to use screen position on events 283 284 this.canshowonmouseevent = (self.opt.autohidemode != "scroll"); 285 286 // Events jump table 287 this.onmousedown = false; 288 this.onmouseup = false; 289 this.onmousemove = false; 290 this.onmousewheel = false; 291 this.onkeypress = false; 292 this.ongesturezoom = false; 293 this.onclick = false; 294 295 // Nicescroll custom events 296 this.onscrollstart = false; 297 this.onscrollend = false; 298 this.onscrollcancel = false; 299 300 this.onzoomin = false; 301 this.onzoomout = false; 302 303 // Let's start! 304 this.view = false; 305 this.page = false; 306 307 this.scroll = { 308 x: 0, 309 y: 0 310 }; 311 this.scrollratio = { 312 x: 0, 313 y: 0 314 }; 315 this.cursorheight = 20; 316 this.scrollvaluemax = 0; 317 318 // http://dev.w3.org/csswg/css-writing-modes-3/#logical-to-physical 319 // http://dev.w3.org/csswg/css-writing-modes-3/#svg-writing-mode 320 if (this.opt.rtlmode == "auto") { 321 var target = this.win[0] == window ? this.body : this.win; 322 var writingMode = target.css("writing-mode") || target.css("-webkit-writing-mode") || target.css("-ms-writing-mode") || target.css("-moz-writing-mode"); 323 324 if (writingMode == "horizontal-tb" || writingMode == "lr-tb" || writingMode == "") { 325 this.isrtlmode = (target.css("direction") == "rtl"); 326 this.isvertical = false; 327 } else { 328 this.isrtlmode = (writingMode == "vertical-rl" || writingMode == "tb" || writingMode == "tb-rl" || writingMode == "rl-tb"); 329 this.isvertical = (writingMode == "vertical-rl" || writingMode == "tb" || writingMode == "tb-rl"); 330 } 331 } else { 332 this.isrtlmode = (this.opt.rtlmode === true); 333 this.isvertical = false; 334 } 335 // this.checkrtlmode = false; 336 337 this.scrollrunning = false; 338 339 this.scrollmom = false; 340 341 this.observer = false; // observer div changes 342 this.observerremover = false; // observer on parent for remove detection 343 this.observerbody = false; // observer on body for position change 344 345 do { 346 this.id = "ascrail" + (ascrailcounter++); 347 } while (document.getElementById(this.id)); 348 349 this.rail = false; 350 this.cursor = false; 351 this.cursorfreezed = false; 352 this.selectiondrag = false; 353 354 this.zoom = false; 355 this.zoomactive = false; 356 357 this.hasfocus = false; 358 this.hasmousefocus = false; 359 360 this.visibility = true; 361 this.railslocked = false; // locked by resize 362 this.locked = false; // prevent lost of locked status sets by user 363 this.hidden = false; // rails always hidden 364 this.cursoractive = true; // user can interact with cursors 365 366 this.wheelprevented = false; //prevent mousewheel event 367 368 this.overflowx = self.opt.overflowx; 369 this.overflowy = self.opt.overflowy; 370 371 this.nativescrollingarea = false; 372 this.checkarea = 0; 373 374 this.events = []; // event list for unbind 375 376 this.saved = {}; // style saved 377 378 this.delaylist = {}; 379 this.synclist = {}; 380 381 this.lastdeltax = 0; 382 this.lastdeltay = 0; 383 384 this.detected = getBrowserDetection(); 385 386 var cap = $.extend({}, this.detected); 387 388 this.canhwscroll = (cap.hastransform && self.opt.hwacceleration); 389 this.ishwscroll = (this.canhwscroll && self.haswrapper); 390 391 if (!this.isrtlmode) { 392 this.hasreversehr = false; 393 } else if (this.isvertical) { // RTL mode with reverse horizontal axis 394 this.hasreversehr = !(cap.iswebkit || cap.isie || cap.isie11); 395 } else { 396 this.hasreversehr = !(cap.iswebkit || (cap.isie && !cap.isie10 && !cap.isie11)); 397 } 398 399 this.istouchcapable = false; // desktop devices with touch screen support 400 401 //## Check WebKit-based desktop with touch support 402 //## + Firefox 18 nightly build (desktop) false positive (or desktop with touch support) 403 404 if (!cap.cantouch && (cap.hasw3ctouch||cap.hasmstouch)) { // desktop device with multiple input 405 this.istouchcapable = true; 406 } else if (cap.cantouch && !cap.isios && !cap.isandroid && (cap.iswebkit || cap.ismozilla)) { 407 this.istouchcapable = true; 408// cap.cantouch = false; // parse normal desktop events 409 } 410 411 //## disable MouseLock API on user request 412 if (!self.opt.enablemouselockapi) { 413 cap.hasmousecapture = false; 414 cap.haspointerlock = false; 415 } 416 417/* deprecated 418 this.delayed = function(name, fn, tm, lazy) { 419 }; 420*/ 421 422/* 423 this.debounced = function(name, fn, tm) { 424 if (!self) return; 425 var dd = self.delaylist[name]; 426 self.delaylist[name] = fn; 427 if (!dd) { 428 self.debouncedelayed = setTimeout(function() { 429 if (!self) return; 430 var fn = self.delaylist[name]; 431 self.delaylist[name] = false; 432 fn.call(self); 433 }, tm); 434 } 435 }; 436*/ 437 438 this.debounced = function(name, fn, tm) { 439 if (!self) return; 440 var dd = self.delaylist[name]||false; 441 if (!dd) { 442 //fixed loop call fn:checkSelectionScroll 443 //fn.call(self); 444 self.delaylist[name] = { 445 h: setAnimationFrame(function(){ 446 self.delaylist[name].fn.call(self); 447 self.delaylist[name] = false; 448 }, tm) 449 }; 450 fn.call(self); 451 } 452 self.delaylist[name].fn = fn; 453 }; 454 455 var _onsync = false; 456 457 this.synched = function(name, fn) { 458 459 function requestSync() { 460 if (_onsync) return; 461 setAnimationFrame(function() { 462 if (!self) return; 463 _onsync = false; 464 for (var nn in self.synclist) { 465 var fn = self.synclist[nn]; 466 if (fn) fn.call(self); 467 self.synclist[nn] = false; 468 } 469 }); 470 _onsync = true; 471 } 472 473 self.synclist[name] = fn; 474 requestSync(); 475 return name; 476 }; 477 478 this.unsynched = function(name) { 479 if (self.synclist[name]) self.synclist[name] = false; 480 }; 481 482 this.css = function(el, pars) { // save & set 483 for (var n in pars) { 484 self.saved.css.push([el, n, el.css(n)]); 485 el.css(n, pars[n]); 486 } 487 }; 488 489 this.scrollTop = function(val) { 490 return (val === undefined) ? self.getScrollTop() : self.setScrollTop(val); 491 }; 492 493 this.scrollLeft = function(val) { 494 return (val === undefined) ? self.getScrollLeft() : self.setScrollLeft(val); 495 }; 496 497 // derived by by Dan Pupius www.pupius.net 498 var BezierClass = function(st, ed, spd, p1, p2, p3, p4) { 499 500 this.st = st; 501 this.ed = ed; 502 this.spd = spd; 503 504 this.p1 = p1 || 0; 505 this.p2 = p2 || 1; 506 this.p3 = p3 || 0; 507 this.p4 = p4 || 1; 508
509 this.ts = (new Date()).getTime(); 510 this.df = this.ed - this.st; 511 }; 512 BezierClass.prototype = { 513 B2: function(t) { 514 return 3 * t * t * (1 - t); 515 }, 516 B3: function(t) { 517 return 3 * t * (1 - t) * (1 - t); 518 }, 519 B4: function(t) { 520 return (1 - t) * (1 - t) * (1 - t); 521 }, 522 getNow: function() { 523 var nw = (new Date()).getTime(); 524 var pc = 1 - ((nw - this.ts) / this.spd); 525 var bz = this.B2(pc) + this.B3(pc) + this.B4(pc); 526 return (pc < 0) ? this.ed : this.st + Math.round(this.df * bz); 527 }, 528 update: function(ed, spd) { 529 this.st = this.getNow(); 530 this.ed = ed; 531 this.spd = spd; 532 this.ts = (new Date()).getTime(); 533 this.df = this.ed - this.st; 534 return this; 535 } 536 }; 537 538 //derived from http://stackoverflow.com/questions/11236090/ 539 function getMatrixValues() { 540 var tr = self.doc.css(cap.trstyle); 541 if (tr && (tr.substr(0, 6) == "matrix")) { 542 return tr.replace(/^.*\((.*)\)$/g, "$1").replace(/px/g, '').split(/, +/); 543 } 544 return false; 545 } 546 547 if (this.ishwscroll) { 548 // hw accelerated scroll 549 this.doc.translate = { 550 x: 0, 551 y: 0, 552 tx: "0px", 553 ty: "0px" 554 }; 555 556 //this one can help to enable hw accel on ios6 http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/ 557 if (cap.hastranslate3d && cap.isios) this.doc.css("-webkit-backface-visibility", "hidden"); // prevent flickering http://stackoverflow.com/questions/3461441/ 558
vendor: 11,434 bytes, lines 559-866
559 this.getScrollTop = function(last) { 560 if (!last) { 561 var mtx = getMatrixValues(); 562 if (mtx) return (mtx.length == 16) ? -mtx[13] : -mtx[5]; //matrix3d 16 on IE10 563 if (self.timerscroll && self.timerscroll.bz) return self.timerscroll.bz.getNow(); 564 } 565 return self.doc.translate.y; 566 }; 567 568 this.getScrollLeft = function(last) { 569 if (!last) { 570 var mtx = getMatrixValues(); 571 if (mtx) return (mtx.length == 16) ? -mtx[12] : -mtx[4]; //matrix3d 16 on IE10 572 if (self.timerscroll && self.timerscroll.bh) return self.timerscroll.bh.getNow(); 573 } 574 return self.doc.translate.x; 575 }; 576 577 this.notifyScrollEvent = function(el) { 578 var e = document.createEvent("UIEvents"); 579 e.initUIEvent("scroll", false, true, window, 1); 580 e.niceevent = true; 581 el.dispatchEvent(e); 582 }; 583 584 var cxscrollleft = (this.isrtlmode) ? 1 : -1; 585 586 if (cap.hastranslate3d && self.opt.enabletranslate3d) { 587 this.setScrollTop = function(val, silent) { 588 self.doc.translate.y = val; 589 self.doc.translate.ty = (val * -1) + "px"; 590 self.doc.css(cap.trstyle, "translate3d(" + self.doc.translate.tx + "," + self.doc.translate.ty + ",0px)"); 591 if (!silent) self.notifyScrollEvent(self.win[0]); 592 }; 593 this.setScrollLeft = function(val, silent) { 594 self.doc.translate.x = val; 595 self.doc.translate.tx = (val * cxscrollleft) + "px"; 596 self.doc.css(cap.trstyle, "translate3d(" + self.doc.translate.tx + "," + self.doc.translate.ty + ",0px)"); 597 if (!silent) self.notifyScrollEvent(self.win[0]); 598 }; 599 } else { 600 this.setScrollTop = function(val, silent) { 601 self.doc.translate.y = val; 602 self.doc.translate.ty = (val * -1) + "px"; 603 self.doc.css(cap.trstyle, "translate(" + self.doc.translate.tx + "," + self.doc.translate.ty + ")"); 604 if (!silent) self.notifyScrollEvent(self.win[0]); 605 }; 606 this.setScrollLeft = function(val, silent) { 607 self.doc.translate.x = val; 608 self.doc.translate.tx = (val * cxscrollleft) + "px"; 609 self.doc.css(cap.trstyle, "translate(" + self.doc.translate.tx + "," + self.doc.translate.ty + ")"); 610 if (!silent) self.notifyScrollEvent(self.win[0]); 611 }; 612 } 613 } else { 614 // native scroll 615 this.getScrollTop = function() { 616 return self.docscroll.scrollTop(); 617 }; 618 this.setScrollTop = function(val) { 619 return setTimeout(function() {(self)&&self.docscroll.scrollTop(val)}, 1); 620 }; 621 this.getScrollLeft = function() { 622 var val; 623 if (!self.hasreversehr) { 624 val = self.docscroll.scrollLeft(); 625 } else if (self.detected.ismozilla) { 626 val = self.page.maxw - Math.abs(self.docscroll.scrollLeft()); 627 } else { 628 val = self.page.maxw - self.docscroll.scrollLeft(); 629 } 630 return val; 631 }; 632 this.setScrollLeft = function(val) { 633 return setTimeout(function() { 634 if (!self) return; 635 if (self.hasreversehr) { 636 if (self.detected.ismozilla) { 637 val = -(self.page.maxw - val); 638 } else { 639 val = self.page.maxw - val; 640 } 641 } 642 return self.docscroll.scrollLeft(val); 643 }, 1); 644 }; 645 } 646 647 this.getTarget = function(e) { 648 if (!e) return false; 649 if (e.target) return e.target; 650 if (e.srcElement) return e.srcElement; 651 return false; 652 }; 653 654 this.hasParent = function(e, id) { 655 if (!e) return false; 656 var el = e.target || e.srcElement || e || false; 657 while (el && el.id != id) { 658 el = el.parentNode || false; 659 } 660 return (el !== false); 661 }; 662 663 function getZIndex() { 664 var dom = self.win; 665 if ("zIndex" in dom) return dom.zIndex(); // use jQuery UI method when available 666 while (dom.length > 0) { 667 if (dom[0].nodeType == 9) return false; 668 var zi = dom.css('zIndex'); 669 if (!isNaN(zi) && zi != 0) return parseInt(zi); 670 dom = dom.parent(); 671 } 672 return false; 673 } 674 675 //inspired by http://forum.jquery.com/topic/width-includes-border-width-when-set-to-thin-medium-thick-in-ie 676 var _convertBorderWidth = { 677 "thin": 1, 678 "medium": 3, 679 "thick": 5 680 }; 681 682 function getWidthToPixel(dom, prop, chkheight) { 683 var wd = dom.css(prop); 684 var px = parseFloat(wd); 685 if (isNaN(px)) { 686 px = _convertBorderWidth[wd] || 0; 687 var brd = (px == 3) ? ((chkheight) ? (self.win.outerHeight() - self.win.innerHeight()) : (self.win.outerWidth() - self.win.innerWidth())) : 1; //DON'T TRUST CSS 688 if (self.isie8 && px) px += 1; 689 return (brd) ? px : 0; 690 } 691 return px; 692 } 693 694 this.getDocumentScrollOffset = function() { 695 return { 696 top: window.pageYOffset || document.documentElement.scrollTop, 697 left: window.pageXOffset || document.documentElement.scrollLeft 698 }; 699 }; 700 701 this.getOffset = function() { 702 if (self.isfixed) { 703 var ofs = self.win.offset(); // fix Chrome auto issue (when right/bottom props only) 704 var scrl = self.getDocumentScrollOffset(); 705 ofs.top-=scrl.top; 706 ofs.left-=scrl.left; 707 return ofs; 708 } 709 var ww = self.win.offset(); 710 if (!self.viewport) return ww; 711 var vp = self.viewport.offset(); 712 return { 713 top: ww.top - vp.top,// + self.viewport.scrollTop(), 714 left: ww.left - vp.left // + self.viewport.scrollLeft() 715 }; 716 }; 717 718 this.updateScrollBar = function(len) { 719 var pos, off; 720 if (self.ishwscroll) { 721 self.rail.css({ //** 722 height: self.win.innerHeight() - (self.opt.railpadding.top + self.opt.railpadding.bottom) 723 }); 724 if (self.railh) self.railh.css({ //** 725 width: self.win.innerWidth() - (self.opt.railpadding.left + self.opt.railpadding.right) 726 }); 727 728 } else { 729 var wpos = self.getOffset(); 730 pos = { 731 top: wpos.top, 732 left: wpos.left - (self.opt.railpadding.left + self.opt.railpadding.right) 733 }; 734 pos.top += getWidthToPixel(self.win, 'border-top-width', true); 735 pos.left += (self.rail.align) ? self.win.outerWidth() - getWidthToPixel(self.win, 'border-right-width') - self.rail.width : getWidthToPixel(self.win, 'border-left-width'); 736 737 off = self.opt.railoffset; 738 if (off) { 739 if (off.top) pos.top += off.top; 740 if (off.left) pos.left += off.left; 741 } 742 743 if (!self.railslocked) self.rail.css({ 744 top: pos.top, 745 left: pos.left, 746 height: ((len) ? len.h : self.win.innerHeight()) - (self.opt.railpadding.top + self.opt.railpadding.bottom) 747 }); 748 749 if (self.zoom) { 750 self.zoom.css({ 751 top: pos.top + 1, 752 left: (self.rail.align == 1) ? pos.left - 20 : pos.left + self.rail.width + 4 753 }); 754 } 755 756 if (self.railh && !self.railslocked) { 757 pos = { 758 top: wpos.top, 759 left: wpos.left 760 }; 761 off = self.opt.railhoffset; 762 if (off) { 763 if (off.top) pos.top += off.top; 764 if (off.left) pos.left += off.left; 765 } 766 var y = (self.railh.align) ? pos.top + getWidthToPixel(self.win, 'border-top-width', true) + self.win.innerHeight() - self.railh.height : pos.top + getWidthToPixel(self.win, 'border-top-width', true); 767 var x = pos.left + getWidthToPixel(self.win, 'border-left-width'); 768 self.railh.css({ 769 top: y - (self.opt.railpadding.top + self.opt.railpadding.bottom), 770 left: x, 771 width: self.railh.width 772 }); 773 } 774 775 } 776 }; 777 778 this.doRailClick = function(e, dbl, hr) { 779 var fn, pg, cur, pos; 780 781 if (self.railslocked) return; 782 self.cancelEvent(e); 783 784 if (dbl) { 785 fn = (hr) ? self.doScrollLeft : self.doScrollTop; 786 cur = (hr) ? ((e.pageX - self.railh.offset().left - (self.cursorwidth / 2)) * self.scrollratio.x) : ((e.pageY - self.rail.offset().top - (self.cursorheight / 2)) * self.scrollratio.y); 787 fn(cur); 788 } else { 789 fn = (hr) ? self.doScrollLeftBy : self.doScrollBy; 790 cur = (hr) ? self.scroll.x : self.scroll.y; 791 pos = (hr) ? e.pageX - self.railh.offset().left : e.pageY - self.rail.offset().top; 792 pg = (hr) ? self.view.w : self.view.h; 793 fn((cur >= pos) ? pg: -pg);// (cur >= pos) ? fn(pg): fn(-pg); 794 } 795 796 }; 797 798 self.hasanimationframe = (setAnimationFrame); 799 self.hascancelanimationframe = (clearAnimationFrame); 800 801 if (!self.hasanimationframe) { 802 setAnimationFrame = function(fn) { 803 return setTimeout(fn, 15 - Math.floor((+new Date()) / 1000) % 16); 804 }; // 1000/60)}; 805 clearAnimationFrame = clearTimeout; 806 } else if (!self.hascancelanimationframe) clearAnimationFrame = function() { 807 self.cancelAnimationFrame = true; 808 }; 809 810 this.init = function() { 811 812 self.saved.css = []; 813 814 if (cap.isie7mobile) return true; // SORRY, DO NOT WORK! 815 if (cap.isoperamini) return true; // SORRY, DO NOT WORK! 816 817 var _touchaction = (cap.isie10) ? '-ms-touch-action' : 'touch-action'; 818 if (cap.hasmstouch) self.css((self.ispage) ? $("html") : self.win, { 819 _touchaction: 'none' 820 }); 821 822 var _scrollyhidden = (cap.ismodernie||cap.isie10) ? {'-ms-overflow-style':'none'} : {'overflow-y':'hidden'}; // IE is always a world apart! 823 824 self.zindex = "auto"; 825 if (!self.ispage && self.opt.zindex == "auto") { 826 self.zindex = getZIndex() || "auto"; 827 } else { 828 self.zindex = self.opt.zindex; 829 } 830 831 if (!self.ispage && self.zindex != "auto" && self.zindex > globalmaxzindex) { 832 globalmaxzindex = self.zindex; 833 } 834 835 if (self.isie && self.zindex == 0 && self.opt.zindex == "auto") { // fix IE auto == 0 836 self.zindex = "auto"; 837 } 838 839 if (!self.ispage || (!cap.cantouch && !cap.isieold && !cap.isie9mobile)) { 840 841 var cont = self.docscroll; 842 if (self.ispage) cont = (self.haswrapper) ? self.win : self.doc; 843 844 if (!cap.isie9mobile) self.css(cont, _scrollyhidden); 845 846 if (self.ispage && cap.isie7) { 847 if (self.doc[0].nodeName == 'BODY') self.css($("html"), { 848 'overflow-y': 'hidden' 849 }); //IE7 double scrollbar issue 850 else if (self.doc[0].nodeName == 'HTML') self.css($("body"), _scrollyhidden); //IE7 double scrollbar issue 851 } 852 853 if (cap.isios && !self.ispage && !self.haswrapper) self.css($("body"), { 854 "-webkit-overflow-scrolling": "touch" 855 }); //force hw acceleration 856 857 var cursor = $(document.createElement('div')); 858 cursor.css({ 859 position: "relative", 860 top: 0, 861 "float": "right", 862 width: self.opt.cursorwidth, 863 height: 0, 864 'background-color': self.opt.cursorcolor, 865 border: self.opt.cursorborder, 866 'background-clip': 'padding-box',
867 '-webkit-border-radius': self.opt.cursorborderradius, 868 '-moz-border-radius': self.opt.cursorborderradius, 869 'border-radius': self.opt.cursorborderradius 870 }); 871 872 cursor.hborder = parseFloat(cursor.outerHeight() - cursor.innerHeight()); 873 874 cursor.addClass('nicescroll-cursors'); 875 876 self.cursor = cursor; 877 878 var rail = $(document.createElement('div')); 879 rail.attr('id', self.id); 880 rail.addClass('nicescroll-rails nicescroll-rails-vr'); 881 882 var v, a, kp = ["left","right","top","bottom"]; //** 883 for (var n in kp) { 884 a = kp[n]; 885 v = self.opt.railpadding[a]; 886 (v) ? rail.css("padding-"+a,v+"px") : self.opt.railpadding[a] = 0; 887 } 888 889 rail.append(cursor); 890 891 rail.width = Math.max(parseFloat(self.opt.cursorwidth), cursor.outerWidth()); 892 rail.css({ 893 width: rail.width + "px", 894 zIndex: self.zindex, 895 background: self.opt.background, 896 cursor: "default" 897 }); 898 899 rail.visibility = true; 900 rail.scrollable = true; 901 902 rail.align = (self.opt.railalign == "left") ? 0 : 1; 903 904 self.rail = rail; 905 906 self.rail.drag = false; 907 908 var zoom = false; 909 if (self.opt.boxzoom && !self.ispage && !cap.isieold) { 910 zoom = document.createElement('div'); 911 912 self.bind(zoom, "click", self.doZoom); 913 self.bind(zoom, "mouseenter", function() { 914 self.zoom.css('opacity', self.opt.cursoropacitymax); 915 }); 916 self.bind(zoom, "mouseleave", function() { 917 self.zoom.css('opacity', self.opt.cursoropacitymin); 918 }); 919 920 self.zoom = $(zoom); 921 self.zoom.css({ 922 cursor: "pointer", 923 zIndex: self.zindex, 924 backgroundImage: 'url(' + self.opt.scriptpath + 'zoomico.png)', 925 height: 18, 926 width: 18, 927 backgroundPosition: '0px 0px' 928 }); 929 if (self.opt.dblclickzoom) self.bind(self.win, "dblclick", self.doZoom); 930 if (cap.cantouch && self.opt.gesturezoom) { 931 self.ongesturezoom = function(e) { 932 if (e.scale > 1.5) self.doZoomIn(e); 933 if (e.scale < 0.8) self.doZoomOut(e); 934 return self.cancelEvent(e); 935 }; 936 self.bind(self.win, "gestureend", self.ongesturezoom); 937 } 938 } 939 940 // init HORIZ 941 942 self.railh = false; 943 var railh; 944 945 if (self.opt.horizrailenabled) { 946 947 self.css(cont, { 948 overflowX: 'hidden' 949 }); 950 951 var cursor = $(document.createElement('div')); 952 cursor.css({ 953 position: "absolute", 954 top: 0, 955 height: self.opt.cursorwidth, 956 width: 0, 957 backgroundColor: self.opt.cursorcolor, 958 border: self.opt.cursorborder, 959 backgroundClip: 'padding-box', 960 '-webkit-border-radius': self.opt.cursorborderradius, 961 '-moz-border-radius': self.opt.cursorborderradius, 962 'border-radius': self.opt.cursorborderradius 963 }); 964 965 if (cap.isieold) cursor.css('overflow', 'hidden'); //IE6 horiz scrollbar issue 966 967 cursor.wborder = parseFloat(cursor.outerWidth() - cursor.innerWidth()); 968 969 cursor.addClass('nicescroll-cursors'); 970 971 self.cursorh = cursor; 972 973 railh = $(document.createElement('div')); 974 railh.attr('id', self.id + '-hr'); 975 railh.addClass('nicescroll-rails nicescroll-rails-hr'); 976 railh.height = Math.max(parseFloat(self.opt.cursorwidth), cursor.outerHeight()); 977 railh.css({ 978 height: railh.height + "px", 979 'zIndex': self.zindex, 980 "background": self.opt.background 981 }); 982 983 railh.append(cursor); 984 985 railh.visibility = true; 986 railh.scrollable = true; 987 988 railh.align = (self.opt.railvalign == "top") ? 0 : 1; 989 990 self.railh = railh; 991 992 self.railh.drag = false; 993 994 } 995 996 // 997 998 if (self.ispage) { 999 rail.css({ 1000 position: "fixed", 1001 top: 0, 1002 height: "100%" 1003 }); 1004 (rail.align) ? rail.css({ 1005 right: 0 1006 }): rail.css({ 1007 left: 0 1008 }); 1009 self.body.append(rail); 1010 if (self.railh) { 1011 railh.css({ 1012 position: "fixed", 1013 left: 0, 1014 width: "100%" 1015 }); 1016 (railh.align) ? railh.css({ 1017 bottom: 0 1018 }): railh.css({ 1019 top: 0 1020 }); 1021 self.body.append(railh); 1022 } 1023 } else { 1024 if (self.ishwscroll) { 1025 if (self.win.css('position') == 'static') self.css(self.win, { 1026 'position': 'relative' 1027 }); 1028 var bd = (self.win[0].nodeName == 'HTML') ? self.body : self.win; 1029 $(bd).scrollTop(0).scrollLeft(0); // fix rail position if content already scrolled 1030 if (self.zoom) { 1031 self.zoom.css({ 1032 position: "absolute",
1033 top: 1, 1034 right: 0, 1035 "margin-right": rail.width + 4 1036 }); 1037 bd.append(self.zoom); 1038 } 1039 rail.css({ 1040 position: "absolute", 1041 top: 0 1042 }); 1043 (rail.align) ? rail.css({ 1044 right: 0 1045 }): rail.css({ 1046 left: 0 1047 }); 1048 bd.append(rail); 1049 if (railh) { 1050 railh.css({ 1051 position: "absolute", 1052 left: 0, 1053 bottom: 0 1054 }); 1055 (railh.align) ? railh.css({ 1056 bottom: 0 1057 }): railh.css({ 1058 top: 0 1059 }); 1060 bd.append(railh); 1061 } 1062 } else { 1063 self.isfixed = (self.win.css("position") == "fixed"); 1064 var rlpos = (self.isfixed) ? "fixed" : "absolute"; 1065 1066 if (!self.isfixed) self.viewport = self.getViewport(self.win[0]); 1067 if (self.viewport) { 1068 self.body = self.viewport; 1069 if ((/fixed|absolute/.test(self.viewport.css("position"))) == false) self.css(self.viewport, { 1070 "position": "relative" 1071 }); 1072 } 1073 1074 rail.css({ 1075 position: rlpos 1076 }); 1077 if (self.zoom) self.zoom.css({ 1078 position: rlpos 1079 }); 1080 self.updateScrollBar(); 1081 self.body.append(rail); 1082 if (self.zoom) self.body.append(self.zoom); 1083 if (self.railh) { 1084 railh.css({ 1085 position: rlpos 1086 }); 1087 self.body.append(railh); 1088 } 1089 } 1090 1091 if (cap.isios) self.css(self.win, { 1092 '-webkit-tap-highlight-color': 'rgba(0,0,0,0)', 1093 '-webkit-touch-callout': 'none' 1094 }); // prevent grey layer on click 1095 1096 if (cap.isie && self.opt.disableoutline) self.win.attr("hideFocus", "true"); // IE, prevent dotted rectangle on focused div 1097 if (cap.iswebkit && self.opt.disableoutline) self.win.css('outline', 'none'); // Webkit outline 1098 //if (cap.isopera&&self.opt.disableoutline) self.win.css({"outline":"0"}); // Opera 12- to test [TODO] 1099 1100 } 1101 1102 if (self.opt.autohidemode === false) { 1103 self.autohidedom = false; 1104 self.rail.css({ 1105 opacity: self.opt.cursoropacitymax 1106 }); 1107 if (self.railh) self.railh.css({ 1108 opacity: self.opt.cursoropacitymax 1109 }); 1110 } else if ((self.opt.autohidemode === true) || (self.opt.autohidemode === "leave")) { 1111 self.autohidedom = $().add(self.rail); 1112 if (cap.isie8) self.autohidedom = self.autohidedom.add(self.cursor); 1113 if (self.railh) self.autohidedom = self.autohidedom.add(self.railh); 1114 if (self.railh && cap.isie8) self.autohidedom = self.autohidedom.add(self.cursorh); 1115 } else if (self.opt.autohidemode == "scroll") { 1116 self.autohidedom = $().add(self.rail); 1117 if (self.railh) self.autohidedom = self.autohidedom.add(self.railh); 1118 } else if (self.opt.autohidemode == "cursor") { 1119 self.autohidedom = $().add(self.cursor); 1120 if (self.railh) self.autohidedom = self.autohidedom.add(self.cursorh); 1121 } else if (self.opt.autohidemode == "hidden") { 1122 self.autohidedom = false; 1123 self.hide(); 1124 self.railslocked = false; 1125 } 1126 1127 if (cap.isie9mobile) { 1128 1129 self.scrollmom = new ScrollMomentumClass2D(self); 1130 1131 self.onmangotouch = function() { 1132 var py = self.getScrollTop(); 1133 var px = self.getScrollLeft(); 1134 1135 if ((py == self.scrollmom.lastscrolly) && (px == self.scrollmom.lastscrollx)) return true; 1136 1137 var dfy = py - self.mangotouch.sy; 1138 var dfx = px - self.mangotouch.sx; 1139 var df = Math.round(Math.sqrt(Math.pow(dfx, 2) + Math.pow(dfy, 2))); 1140 if (df == 0) return; 1141 1142 var dry = (dfy < 0) ? -1 : 1; 1143 var drx = (dfx < 0) ? -1 : 1; 1144 1145 var tm = +new Date(); 1146 if (self.mangotouch.lazy) clearTimeout(self.mangotouch.lazy); 1147 1148 if (((tm - self.mangotouch.tm) > 80) || (self.mangotouch.dry != dry) || (self.mangotouch.drx != drx)) { 1149 self.scrollmom.stop(); 1150 self.scrollmom.reset(px, py); 1151 self.mangotouch.sy = py; 1152 self.mangotouch.ly = py; 1153 self.mangotouch.sx = px;
1154 self.mangotouch.lx = px; 1155 self.mangotouch.dry = dry; 1156 self.mangotouch.drx = drx; 1157 self.mangotouch.tm = tm; 1158 } else { 1159 1160 self.scrollmom.stop(); 1161 self.scrollmom.update(self.mangotouch.sx - dfx, self.mangotouch.sy - dfy); 1162 self.mangotouch.tm = tm; 1163 1164 var ds = Math.max(Math.abs(self.mangotouch.ly - py), Math.abs(self.mangotouch.lx - px)); 1165 self.mangotouch.ly = py; 1166 self.mangotouch.lx = px; 1167 1168 if (ds > 2) { 1169 self.mangotouch.lazy = setTimeout(function() { 1170 self.mangotouch.lazy = false; 1171 self.mangotouch.dry = 0; 1172 self.mangotouch.drx = 0; 1173 self.mangotouch.tm = 0; 1174 self.scrollmom.doMomentum(30); 1175 }, 100); 1176 } 1177 } 1178 }; 1179 1180 var top = self.getScrollTop(); 1181 var lef = self.getScrollLeft(); 1182 self.mangotouch = { 1183 sy: top, 1184 ly: top, 1185 dry: 0, 1186 sx: lef, 1187 lx: lef, 1188 drx: 0, 1189 lazy: false, 1190 tm: 0 1191 }; 1192 1193 self.bind(self.docscroll, "scroll", self.onmangotouch); 1194 1195 } else { 1196 1197 if (cap.cantouch || self.istouchcapable || self.opt.touchbehavior || cap.hasmstouch) { 1198 1199 self.scrollmom = new ScrollMomentumClass2D(self); 1200 1201 self.ontouchstart = function(e) { 1202 if (e.pointerType && e.pointerType != 2 && e.pointerType != "touch") return false; 1203 1204 self.hasmoving = false; 1205 1206 if (!self.railslocked) { 1207 var tg; 1208 if (cap.hasmstouch) { 1209 tg = (e.target) ? e.target : false; 1210 while (tg) { 1211 var nc = $(tg).getNiceScroll(); 1212 if ((nc.length > 0) && (nc[0].me == self.me)) break; 1213 if (nc.length > 0) return false; 1214 if ((tg.nodeName == 'DIV') && (tg.id == self.id)) break; 1215 tg = (tg.parentNode) ? tg.parentNode : false; 1216 } 1217 } 1218 1219 self.cancelScroll(); 1220 1221 tg = self.getTarget(e); 1222 1223 if (tg) { 1224 var skp = (/INPUT/i.test(tg.nodeName)) && (/range/i.test(tg.type)); 1225 if (skp) return self.stopPropagation(e); 1226 } 1227 1228 if (!("clientX" in e) && ("changedTouches" in e)) { 1229 e.clientX = e.changedTouches[0].clientX; 1230 e.clientY = e.changedTouches[0].clientY; 1231 } 1232 1233 if (self.forcescreen) { 1234 var le = e; 1235 e = { 1236 "original": (e.original) ? e.original : e 1237 }; 1238 e.clientX = le.screenX; 1239 e.clientY = le.screenY; 1240 } 1241 1242 self.rail.drag = { 1243 x: e.clientX, 1244 y: e.clientY, 1245 sx: self.scroll.x, 1246 sy: self.scroll.y, 1247 st: self.getScrollTop(), 1248 sl: self.getScrollLeft(), 1249 pt: 2, 1250 dl: false 1251 }; 1252 1253 if (self.ispage || !self.opt.directionlockdeadzone) { 1254 self.rail.drag.dl = "f"; 1255 } else { 1256 1257 var view = { 1258 w: $(window).width(), 1259 h: $(window).height() 1260 }; 1261 1262 var page = { 1263 w: Math.max(document.body.scrollWidth, document.documentElement.scrollWidth), 1264 h: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) 1265 }; 1266 1267 var maxh = Math.max(0, page.h - view.h); 1268 var maxw = Math.max(0, page.w - view.w); 1269 1270 if (!self.rail.scrollable && self.railh.scrollable) self.rail.drag.ck = (maxh > 0) ? "v" : false; 1271 else if (self.rail.scrollable && !self.railh.scrollable) self.rail.drag.ck = (maxw > 0) ? "h" : false; 1272 else self.rail.drag.ck = false; 1273 if (!self.rail.drag.ck) self.rail.drag.dl = "f"; 1274 } 1275 1276 if (self.opt.touchbehavior && self.isiframe && cap.isie) { 1277 var wp = self.win.position(); 1278 self.rail.drag.x += wp.left; 1279 self.rail.drag.y += wp.top; 1280 } 1281 1282 self.hasmoving = false; 1283 self.lastmouseup = false; 1284 self.scrollmom.reset(e.clientX, e.clientY); 1285 1286 if (!cap.cantouch && !this.istouchcapable && !e.pointerType) { 1287 1288 var ip = (tg) ? /INPUT|SELECT|TEXTAREA/i.test(tg.nodeName) : false; 1289 if (!ip) { 1290 if (!self.ispage && cap.hasmousecapture) tg.setCapture(); 1291 if (self.opt.touchbehavior) { 1292 if (tg.onclick && !(tg._onclick || false)) { // intercept DOM0 onclick event 1293 tg._onclick = tg.onclick;
1294 tg.onclick = function(e) { 1295 if (self.hasmoving) return false; 1296 tg._onclick.call(this, e); 1297 }; 1298 } 1299 return self.cancelEvent(e); 1300 } 1301 return self.stopPropagation(e); 1302 } 1303 1304 if (/SUBMIT|CANCEL|BUTTON/i.test($(tg).attr('type'))) { 1305 self.preventclick = { 1306 "tg": tg, 1307 "click": false 1308 }; 1309 } 1310 1311 } 1312 } 1313 1314 }; 1315 1316 self.ontouchend = function(e) { 1317 if (!self.rail.drag) return true; 1318 if (self.rail.drag.pt == 2) { 1319 if (e.pointerType && e.pointerType != 2 && e.pointerType != "touch") return false; 1320 1321 self.scrollmom.doMomentum(); 1322 self.rail.drag = false; 1323 if (self.hasmoving) { 1324 self.lastmouseup = true; 1325 self.hideCursor(); 1326 if (cap.hasmousecapture) document.releaseCapture(); 1327 if (!cap.cantouch) return self.cancelEvent(e); 1328 } 1329 } 1330 else if (self.rail.drag.pt == 1) { 1331 return self.onmouseup(e); 1332 } 1333 1334 }; 1335 1336 var moveneedoffset = (self.opt.touchbehavior && self.isiframe && !cap.hasmousecapture); 1337 1338 self.ontouchmove = function(e, byiframe) { 1339 1340 if (!self.rail.drag) return false; 1341 1342 if (e.targetTouches && self.opt.preventmultitouchscrolling) { 1343 if (e.targetTouches.length > 1) return false; // multitouch 1344 } 1345 1346 if (e.pointerType && e.pointerType != 2 && e.pointerType != "touch") return false; 1347 1348 if (self.rail.drag.pt == 2) { 1349 if (cap.cantouch && (cap.isios) && e.original === undefined) return true; // prevent ios "ghost" events by clickable elements 1350 1351 self.hasmoving = true; 1352 1353 if (self.preventclick && !self.preventclick.click) { 1354 self.preventclick.click = self.preventclick.tg.onclick || false; 1355 self.preventclick.tg.onclick = self.onpreventclick; 1356 } 1357 1358 var ev = $.extend({ 1359 "original": e 1360 }, e); 1361 e = ev; 1362 1363 if (("changedTouches" in e)) { 1364 e.clientX = e.changedTouches[0].clientX; 1365 e.clientY = e.changedTouches[0].clientY; 1366 } 1367 1368 if (self.forcescreen) { 1369 var le = e; 1370 e = { 1371 "original": (e.original) ? e.original : e 1372 }; 1373 e.clientX = le.screenX; 1374 e.clientY = le.screenY; 1375 } 1376 1377 var ofy,ofx; 1378 ofx = ofy = 0; 1379 1380 if (moveneedoffset && !byiframe) { 1381 var wp = self.win.position(); 1382 ofx = -wp.left; 1383 ofy = -wp.top; 1384 } 1385 1386 var fy = e.clientY + ofy; 1387 var my = (fy - self.rail.drag.y); 1388 var fx = e.clientX + ofx; 1389 var mx = (fx - self.rail.drag.x); 1390 1391 var ny = self.rail.drag.st - my; 1392 1393 if (self.ishwscroll && self.opt.bouncescroll) { 1394 if (ny < 0) { 1395 ny = Math.round(ny / 2); 1396 // fy = 0; 1397 } else if (ny > self.page.maxh) { 1398 ny = self.page.maxh + Math.round((ny - self.page.maxh) / 2); 1399 // fy = 0; 1400 } 1401 } else { 1402 if (ny < 0) { 1403 ny = 0; 1404 fy = 0; 1405 } 1406 if (ny > self.page.maxh) { 1407 ny = self.page.maxh;
1408 fy = 0; 1409 } 1410 } 1411 1412 var nx; 1413 if (self.railh && self.railh.scrollable) { 1414 nx = (self.isrtlmode) ? mx - self.rail.drag.sl : self.rail.drag.sl - mx; 1415 1416 if (self.ishwscroll && self.opt.bouncescroll) { 1417 if (nx < 0) { 1418 nx = Math.round(nx / 2); 1419 // fx = 0; 1420 } else if (nx > self.page.maxw) { 1421 nx = self.page.maxw + Math.round((nx - self.page.maxw) / 2); 1422 // fx = 0; 1423 } 1424 } else { 1425 if (nx < 0) { 1426 nx = 0; 1427 fx = 0; 1428 } 1429 if (nx > self.page.maxw) { 1430 nx = self.page.maxw; 1431 fx = 0; 1432 } 1433 } 1434 1435 } 1436 1437 var grabbed = false; 1438 if (self.rail.drag.dl) { 1439 grabbed = true; 1440 if (self.rail.drag.dl == "v") nx = self.rail.drag.sl; 1441 else if (self.rail.drag.dl == "h") ny = self.rail.drag.st; 1442 } else { 1443 var ay = Math.abs(my); 1444 var ax = Math.abs(mx); 1445 var dz = self.opt.directionlockdeadzone; 1446 if (self.rail.drag.ck == "v") { 1447 if (ay > dz && (ax <= (ay * 0.3))) { 1448 self.rail.drag = false; 1449 return true; 1450 } else if (ax > dz) { 1451 self.rail.drag.dl = "f"; 1452 $("body").scrollTop($("body").scrollTop()); // stop iOS native scrolling (when active javascript has blocked) 1453 } 1454 } else if (self.rail.drag.ck == "h") { 1455 if (ax > dz && (ay <= (ax * 0.3))) { 1456 self.rail.drag = false; 1457 return true; 1458 } else if (ay > dz) { 1459 self.rail.drag.dl = "f"; 1460 $("body").scrollLeft($("body").scrollLeft()); // stop iOS native scrolling (when active javascript has blocked) 1461 } 1462 } 1463 } 1464 1465 self.synched("touchmove", function() { 1466 if (self.rail.drag && (self.rail.drag.pt == 2)) { 1467 if (self.prepareTransition) self.prepareTransition(0); 1468 if (self.rail.scrollable) self.setScrollTop(ny); 1469 self.scrollmom.update(fx, fy); 1470 if (self.railh && self.railh.scrollable) { 1471 self.setScrollLeft(nx); 1472 self.showCursor(ny, nx); 1473 } else { 1474 self.showCursor(ny); 1475 } 1476 if (cap.isie10) document.selection.clear(); 1477 } 1478 }); 1479 1480 if (cap.ischrome && self.istouchcapable) grabbed = false; //chrome touch emulation doesn't like! 1481 if (grabbed) return self.cancelEvent(e); 1482 } 1483 else if (self.rail.drag.pt == 1) { // drag on cursor 1484 return self.onmousemove(e); 1485 } 1486 1487 }; 1488 1489 self.ontouchstartCursor = function (e, hronly) { 1490 if (self.rail.drag && self.rail.drag.pt != 3) return; 1491 if (self.locked) return self.cancelEvent(e); 1492 self.cancelScroll(); 1493 self.rail.drag = { 1494 x: e.touches[0].clientX, 1495 y: e.touches[0].clientY, 1496 sx: self.scroll.x, 1497 sy: self.scroll.y, 1498 pt: 3, 1499 hr: (!!hronly) 1500 }; 1501 var tg = self.getTarget(e); 1502 if (!self.ispage && cap.hasmousecapture) tg.setCapture(); 1503 if (self.isiframe && !cap.hasmousecapture) { 1504 self.saved["csspointerevents"] = self.doc.css("pointer-events"); 1505 self.css(self.doc, {"pointer-events": "none"}); 1506 } 1507 return self.cancelEvent(e); 1508 }; 1509 1510 self.ontouchendCursor = function (e) { 1511 if (self.rail.drag) { 1512 if (cap.hasmousecapture) document.releaseCapture(); 1513 if (self.isiframe && !cap.hasmousecapture) self.doc.css("pointer-events", self.saved["csspointerevents"]); 1514 if (self.rail.drag.pt != 3)return; 1515 self.rail.drag = false; 1516 //if (!self.rail.active) self.hideCursor(); 1517 return self.cancelEvent(e); 1518 } 1519 }; 1520 1521 self.ontouchmoveCursor = function (e) { 1522 if (self.rail.drag) { 1523 if (self.rail.drag.pt != 3)return; 1524 1525 self.cursorfreezed = true; 1526 1527 if (self.rail.drag.hr) { 1528 self.scroll.x = self.rail.drag.sx + (e.touches[0].clientX - self.rail.drag.x);
vendor: 25,563 bytes, lines 1529-2166
1529 if (self.scroll.x < 0) self.scroll.x = 0; 1530 var mw = self.scrollvaluemaxw; 1531 if (self.scroll.x > mw) self.scroll.x = mw; 1532 } else { 1533 self.scroll.y = self.rail.drag.sy + (e.touches[0].clientY - self.rail.drag.y); 1534 if (self.scroll.y < 0) self.scroll.y = 0; 1535 var my = self.scrollvaluemax; 1536 if (self.scroll.y > my) self.scroll.y = my; 1537 } 1538 1539 self.synched('touchmove', function () { 1540 if (self.rail.drag && (self.rail.drag.pt == 3)) { 1541 self.showCursor(); 1542 if (self.rail.drag.hr) self.doScrollLeft(Math.round(self.scroll.x * self.scrollratio.x), self.opt.cursordragspeed); 1543 else self.doScrollTop(Math.round(self.scroll.y * self.scrollratio.y), self.opt.cursordragspeed); 1544 } 1545 }); 1546 1547 return self.cancelEvent(e); 1548 } 1549 /* 1550 else { 1551 self.checkarea = true; 1552 } 1553 */ 1554 }; 1555 1556 } 1557 1558 self.onmousedown = function(e, hronly) { 1559 if (self.rail.drag && self.rail.drag.pt != 1) return; 1560 if (self.railslocked) return self.cancelEvent(e); 1561 self.cancelScroll(); 1562 self.rail.drag = { 1563 x: e.clientX, 1564 y: e.clientY, 1565 sx: self.scroll.x, 1566 sy: self.scroll.y, 1567 pt: 1, 1568 hr: (!!hronly) 1569 }; 1570 var tg = self.getTarget(e); 1571 if (!self.ispage && cap.hasmousecapture) tg.setCapture(); 1572 if (self.isiframe && !cap.hasmousecapture) { 1573 self.saved.csspointerevents = self.doc.css("pointer-events"); 1574 self.css(self.doc, { 1575 "pointer-events": "none" 1576 }); 1577 } 1578 self.hasmoving = false; 1579 return self.cancelEvent(e); 1580 }; 1581 1582 self.onmouseup = function(e) { 1583 if (self.rail.drag) { 1584 if (self.rail.drag.pt != 1) return true; 1585 1586 if (cap.hasmousecapture) document.releaseCapture(); 1587 if (self.isiframe && !cap.hasmousecapture) self.doc.css("pointer-events", self.saved.csspointerevents); 1588 self.rail.drag = false; 1589 //if (!self.rail.active) self.hideCursor(); 1590 if (self.hasmoving) self.triggerScrollEnd(); // TODO - check &&!self.scrollrunning 1591 return self.cancelEvent(e); 1592 } 1593 }; 1594 1595 self.onmousemove = function(e) { 1596 if (self.rail.drag) { 1597 if (self.rail.drag.pt != 1) return; 1598 1599 if (cap.ischrome && e.which == 0) return self.onmouseup(e); 1600 1601 self.cursorfreezed = true; 1602 self.hasmoving = true; 1603 1604 if (self.rail.drag.hr) { 1605 self.scroll.x = self.rail.drag.sx + (e.clientX - self.rail.drag.x); 1606 if (self.scroll.x < 0) self.scroll.x = 0; 1607 var mw = self.scrollvaluemaxw; 1608 if (self.scroll.x > mw) self.scroll.x = mw; 1609 } else { 1610 self.scroll.y = self.rail.drag.sy + (e.clientY - self.rail.drag.y); 1611 if (self.scroll.y < 0) self.scroll.y = 0; 1612 var my = self.scrollvaluemax; 1613 if (self.scroll.y > my) self.scroll.y = my; 1614 } 1615 1616 self.synched('mousemove', function() { 1617 if (self.rail.drag && (self.rail.drag.pt == 1)) { 1618 self.showCursor(); 1619 if (self.rail.drag.hr) { 1620 if (self.hasreversehr) { 1621 self.doScrollLeft(self.scrollvaluemaxw-Math.round(self.scroll.x * self.scrollratio.x), self.opt.cursordragspeed); 1622 } else { 1623 self.doScrollLeft(Math.round(self.scroll.x * self.scrollratio.x), self.opt.cursordragspeed); 1624 } 1625 } 1626 else self.doScrollTop(Math.round(self.scroll.y * self.scrollratio.y), self.opt.cursordragspeed); 1627 } 1628 }); 1629 1630 return self.cancelEvent(e); 1631 } 1632 else { 1633 self.checkarea = 0; 1634 } 1635 }; 1636 1637 if (cap.cantouch || self.opt.touchbehavior) { 1638 1639 self.onpreventclick = function(e) { 1640 if (self.preventclick) { 1641 self.preventclick.tg.onclick = self.preventclick.click; 1642 self.preventclick = false; 1643 return self.cancelEvent(e); 1644 } 1645 }; 1646 1647 self.bind(self.win, "mousedown", self.ontouchstart); // control content dragging 1648 1649 self.onclick = (cap.isios) ? false : function(e) { // it needs to check IE11 ??? 1650 if (self.lastmouseup) { 1651 self.lastmouseup = false; 1652 return self.cancelEvent(e); 1653 } else { 1654 return true; 1655 } 1656 }; 1657 1658 if (self.opt.grabcursorenabled && cap.cursorgrabvalue) { 1659 self.css((self.ispage) ? self.doc : self.win, { 1660 'cursor': cap.cursorgrabvalue 1661 }); 1662 self.css(self.rail, { 1663 'cursor': cap.cursorgrabvalue 1664 }); 1665 } 1666 1667 } else { 1668 1669 var checkSelectionScroll = function(e) { 1670 if (!self.selectiondrag) return; 1671 1672 if (e) { 1673 var ww = self.win.outerHeight(); 1674 var df = (e.pageY - self.selectiondrag.top); 1675 if (df > 0 && df < ww) df = 0; 1676 if (df >= ww) df -= ww; 1677 self.selectiondrag.df = df; 1678 } 1679 if (self.selectiondrag.df == 0) return; 1680 1681 var rt = -Math.floor(self.selectiondrag.df / 6) * 2; 1682 self.doScrollBy(rt); 1683 1684 self.debounced("doselectionscroll", function() { 1685 checkSelectionScroll(); 1686 }, 50); 1687 }; 1688 1689 if ("getSelection" in document) { // A grade - Major browsers 1690 self.hasTextSelected = function() { 1691 return (document.getSelection().rangeCount > 0); 1692 }; 1693 } else if ("selection" in document) { //IE9- 1694 self.hasTextSelected = function() { 1695 return (document.selection.type != "None"); 1696 }; 1697 } else { 1698 self.hasTextSelected = function() { // no support 1699 return false; 1700 }; 1701 } 1702 1703 self.onselectionstart = function(e) { 1704/* More testing - severe chrome issues 1705 if (!self.haswrapper&&(e.which&&e.which==2)) { // fool browser to manage middle button scrolling 1706 self.win.css({'overflow':'auto'}); 1707 setTimeout(function(){ 1708 self.win.css({'overflow':''}); 1709 },10); 1710 return true; 1711 } 1712*/ 1713 if (self.ispage) return; 1714 self.selectiondrag = self.win.offset(); 1715 }; 1716 1717 self.onselectionend = function(e) { 1718 self.selectiondrag = false; 1719 }; 1720 self.onselectiondrag = function(e) { 1721 if (!self.selectiondrag) return; 1722 if (self.hasTextSelected()) self.debounced("selectionscroll", function() { 1723 checkSelectionScroll(e); 1724 }, 250); 1725 }; 1726 1727 1728 } 1729 1730 if (cap.hasw3ctouch) { //IE11+ 1731 self.css(self.rail, { 1732 'touch-action': 'none' 1733 }); 1734 self.css(self.cursor, { 1735 'touch-action': 'none' 1736 }); 1737 self.bind(self.win, "pointerdown", self.ontouchstart); 1738 self.bind(document, "pointerup", self.ontouchend); 1739 self.bind(document, "pointermove", self.ontouchmove); 1740 } else if (cap.hasmstouch) { //IE10 1741 self.css(self.rail, { 1742 '-ms-touch-action': 'none' 1743 }); 1744 self.css(self.cursor, { 1745 '-ms-touch-action': 'none' 1746 }); 1747 self.bind(self.win, "MSPointerDown", self.ontouchstart); 1748 self.bind(document, "MSPointerUp", self.ontouchend); 1749 self.bind(document, "MSPointerMove", self.ontouchmove); 1750 self.bind(self.cursor, "MSGestureHold", function(e) { 1751 e.preventDefault(); 1752 }); 1753 self.bind(self.cursor, "contextmenu", function(e) { 1754 e.preventDefault(); 1755 }); 1756 } else if (this.istouchcapable) { //desktop with screen touch enabled 1757 self.bind(self.win, "touchstart", self.ontouchstart); 1758 self.bind(document, "touchend", self.ontouchend); 1759 self.bind(document, "touchcancel", self.ontouchend); 1760 self.bind(document, "touchmove", self.ontouchmove); 1761 } 1762 1763 1764 if (self.opt.cursordragontouch || (!cap.cantouch && !self.opt.touchbehavior)) { 1765 1766 self.rail.css({ 1767 cursor: "default" 1768 }); 1769 self.railh && self.railh.css({ 1770 cursor: "default" 1771 }); 1772 1773 self.jqbind(self.rail, "mouseenter", function() { 1774 if (!self.ispage && !self.win.is(":visible")) return false; 1775 if (self.canshowonmouseevent) self.showCursor(); 1776 self.rail.active = true; 1777 }); 1778 self.jqbind(self.rail, "mouseleave", function() { 1779 self.rail.active = false; 1780 if (!self.rail.drag) self.hideCursor(); 1781 }); 1782 1783 if (self.opt.sensitiverail) { 1784 self.bind(self.rail, "click", function(e) { 1785 self.doRailClick(e, false, false); 1786 }); 1787 self.bind(self.rail, "dblclick", function(e) { 1788 self.doRailClick(e, true, false); 1789 }); 1790 self.bind(self.cursor, "click", function(e) { 1791 self.cancelEvent(e); 1792 }); 1793 self.bind(self.cursor, "dblclick", function(e) { 1794 self.cancelEvent(e); 1795 }); 1796 } 1797 1798 if (self.railh) { 1799 self.jqbind(self.railh, "mouseenter", function() { 1800 if (!self.ispage && !self.win.is(":visible")) return false; 1801 if (self.canshowonmouseevent) self.showCursor(); 1802 self.rail.active = true; 1803 }); 1804 self.jqbind(self.railh, "mouseleave", function() { 1805 self.rail.active = false; 1806 if (!self.rail.drag) self.hideCursor(); 1807 }); 1808 1809 if (self.opt.sensitiverail) { 1810 self.bind(self.railh, "click", function(e) { 1811 self.doRailClick(e, false, true); 1812 }); 1813 self.bind(self.railh, "dblclick", function(e) { 1814 self.doRailClick(e, true, true); 1815 }); 1816 self.bind(self.cursorh, "click", function(e) { 1817 self.cancelEvent(e); 1818 }); 1819 self.bind(self.cursorh, "dblclick", function(e) { 1820 self.cancelEvent(e); 1821 }); 1822 } 1823 1824 } 1825 1826 } 1827 1828 if(self.opt.cursordragontouch && (this.istouchcapable || cap.cantouch)) { 1829 self.bind(self.cursor, "touchstart", self.ontouchstartCursor); 1830 self.bind(self.cursor, "touchmove", self.ontouchmoveCursor); 1831 self.bind(self.cursor, "touchend", self.ontouchendCursor); 1832 self.cursorh && self.bind(self.cursorh, "touchstart", function(e) { 1833 self.ontouchstartCursor(e, true); 1834 }); 1835 self.cursorh && self.bind(self.cursorh, "touchmove", self.ontouchmoveCursor); 1836 self.cursorh && self.bind(self.cursorh, "touchend", self.ontouchendCursor); 1837 } 1838 1839 if (!cap.cantouch && !self.opt.touchbehavior) { 1840 1841 self.bind((cap.hasmousecapture) ? self.win : document, "mouseup", self.onmouseup); 1842 self.bind(document, "mousemove", self.onmousemove); 1843 if (self.onclick) self.bind(document, "click", self.onclick); 1844 1845 self.bind(self.cursor, "mousedown", self.onmousedown); 1846 self.bind(self.cursor, "mouseup", self.onmouseup); 1847 1848 if (self.railh) { 1849 self.bind(self.cursorh, "mousedown", function(e) { 1850 self.onmousedown(e, true); 1851 }); 1852 self.bind(self.cursorh, "mouseup", self.onmouseup); 1853 } 1854 1855 if (!self.ispage && self.opt.enablescrollonselection) { 1856 self.bind(self.win[0], "mousedown", self.onselectionstart); 1857 self.bind(document, "mouseup", self.onselectionend); 1858 self.bind(self.cursor, "mouseup", self.onselectionend); 1859 if (self.cursorh) self.bind(self.cursorh, "mouseup", self.onselectionend); 1860 self.bind(document, "mousemove", self.onselectiondrag); 1861 } 1862 1863 if (self.zoom) { 1864 self.jqbind(self.zoom, "mouseenter", function() { 1865 if (self.canshowonmouseevent) self.showCursor(); 1866 self.rail.active = true; 1867 }); 1868 self.jqbind(self.zoom, "mouseleave", function() { 1869 self.rail.active = false; 1870 if (!self.rail.drag) self.hideCursor(); 1871 }); 1872 } 1873 1874 } else { 1875 1876 self.bind((cap.hasmousecapture) ? self.win : document, "mouseup", self.ontouchend); 1877 self.bind(document, "mousemove", self.ontouchmove); 1878 if (self.onclick) self.bind(document, "click", self.onclick); 1879 1880 if (self.opt.cursordragontouch) { 1881 self.bind(self.cursor, "mousedown", self.onmousedown); 1882 self.bind(self.cursor, "mouseup", self.onmouseup); 1883 //self.bind(self.cursor, "mousemove", self.onmousemove); 1884 self.cursorh && self.bind(self.cursorh, "mousedown", function(e) { 1885 self.onmousedown(e, true); 1886 }); 1887 //self.cursorh && self.bind(self.cursorh, "mousemove", self.onmousemove); 1888 self.cursorh && self.bind(self.cursorh, "mouseup", self.onmouseup); 1889 } else { 1890 self.bind(self.rail, "mousedown", function(e){e.preventDefault();}); // prevent text selection 1891 self.railh&&self.bind(self.railh, "mousedown", function(e){e.preventDefault();}); 1892 } 1893 1894 } 1895 1896 1897 if (self.opt.enablemousewheel) { 1898 if (!self.isiframe) self.mousewheel((cap.isie && self.ispage) ? document : self.win , self.onmousewheel); 1899 self.mousewheel(self.rail, self.onmousewheel); 1900 if (self.railh) self.mousewheel(self.railh, self.onmousewheelhr); 1901 } 1902 1903 if (!self.ispage && !cap.cantouch && !(/HTML|^BODY/.test(self.win[0].nodeName))) { 1904 if (!self.win.attr("tabindex")) self.win.attr({ 1905 "tabindex": tabindexcounter++ 1906 }); 1907 1908 self.jqbind(self.win, "focus", function(e) { 1909 domfocus = (self.getTarget(e)).id || true; 1910 self.hasfocus = true; 1911 if (self.canshowonmouseevent) self.noticeCursor(); 1912 }); 1913 self.jqbind(self.win, "blur", function(e) { 1914 domfocus = false; 1915 self.hasfocus = false; 1916 }); 1917 1918 self.jqbind(self.win, "mouseenter", function(e) { 1919 mousefocus = (self.getTarget(e)).id || true; 1920 self.hasmousefocus = true; 1921 if (self.canshowonmouseevent) self.noticeCursor(); 1922 }); 1923 self.jqbind(self.win, "mouseleave", function() { 1924 mousefocus = false; 1925 self.hasmousefocus = false; 1926 if (!self.rail.drag) self.hideCursor(); 1927 }); 1928 1929 } 1930 1931 } // !ie9mobile 1932 1933 //Thanks to http://www.quirksmode.org !! 1934 self.onkeypress = function(e) { 1935 if (self.railslocked && self.page.maxh == 0) return true; 1936 1937 e = (e) ? e : window.e; 1938 var tg = self.getTarget(e); 1939 if (tg && /INPUT|TEXTAREA|SELECT|OPTION/.test(tg.nodeName)) { 1940 var tp = tg.getAttribute('type') || tg.type || false; 1941 if ((!tp) || !(/submit|button|cancel/i.tp)) return true; 1942 } 1943 1944 if ($(tg).attr('contenteditable')) return true; 1945 1946 if (self.hasfocus || (self.hasmousefocus && !domfocus) || (self.ispage && !domfocus && !mousefocus)) { 1947 var key = e.keyCode; 1948 1949 if (self.railslocked && key != 27) return self.cancelEvent(e); 1950 1951 var ctrl = e.ctrlKey || false; 1952 var shift = e.shiftKey || false; 1953 1954 var ret = false; 1955 switch (key) { 1956 case 38: 1957 case 63233: //safari 1958 self.doScrollBy(24 * 3); 1959 ret = true; 1960 break; 1961 case 40: 1962 case 63235: //safari 1963 self.doScrollBy(-24 * 3); 1964 ret = true; 1965 break; 1966 case 37: 1967 case 63232: //safari 1968 if (self.railh) { 1969 (ctrl) ? self.doScrollLeft(0): self.doScrollLeftBy(24 * 3); 1970 ret = true; 1971 } 1972 break; 1973 case 39: 1974 case 63234: //safari 1975 if (self.railh) { 1976 (ctrl) ? self.doScrollLeft(self.page.maxw): self.doScrollLeftBy(-24 * 3); 1977 ret = true; 1978 } 1979 break; 1980 case 33: 1981 case 63276: // safari 1982 self.doScrollBy(self.view.h); 1983 ret = true; 1984 break; 1985 case 34: 1986 case 63277: // safari 1987 self.doScrollBy(-self.view.h); 1988 ret = true; 1989 break; 1990 case 36: 1991 case 63273: // safari 1992 (self.railh && ctrl) ? self.doScrollPos(0, 0): self.doScrollTo(0); 1993 ret = true; 1994 break; 1995 case 35: 1996 case 63275: // safari 1997 (self.railh && ctrl) ? self.doScrollPos(self.page.maxw, self.page.maxh): self.doScrollTo(self.page.maxh); 1998 ret = true; 1999 break; 2000 case 32: 2001 if (self.opt.spacebarenabled) { 2002 (shift) ? self.doScrollBy(self.view.h): self.doScrollBy(-self.view.h); 2003 ret = true; 2004 } 2005 break; 2006 case 27: // ESC 2007 if (self.zoomactive) { 2008 self.doZoom(); 2009 ret = true; 2010 } 2011 break; 2012 } 2013 if (ret) return self.cancelEvent(e); 2014 } 2015 }; 2016 2017 if (self.opt.enablekeyboard) self.bind(document, (cap.isopera && !cap.isopera12) ? "keypress" : "keydown", self.onkeypress); 2018 2019 self.bind(document, "keydown", function(e) { 2020 var ctrl = e.ctrlKey || false; 2021 if (ctrl) self.wheelprevented = true; 2022 }); 2023 self.bind(document, "keyup", function(e) { 2024 var ctrl = e.ctrlKey || false; 2025 if (!ctrl) self.wheelprevented = false; 2026 }); 2027 self.bind(window,"blur",function(e){ 2028 self.wheelprevented = false; 2029 }); 2030 2031 self.bind(window, 'resize', self.lazyResize); 2032 self.bind(window, 'orientationchange', self.lazyResize); 2033 2034 self.bind(window, "load", self.lazyResize); 2035 2036 if (cap.ischrome && !self.ispage && !self.haswrapper) { //chrome void scrollbar bug - it persists in version 26 2037 var tmp = self.win.attr("style"); 2038 var ww = parseFloat(self.win.css("width")) + 1; 2039 self.win.css('width', ww); 2040 self.synched("chromefix", function() { 2041 self.win.attr("style", tmp); 2042 }); 2043 } 2044 2045 2046 // Trying a cross-browser implementation - good luck! 2047 2048 self.onAttributeChange = function(e) { 2049 self.lazyResize(self.isieold ? 250 : 30); 2050 }; 2051 2052 if ((!self.isie11) && (ClsMutationObserver !== false)) { // IE11 crashes #568 2053 self.observerbody = new ClsMutationObserver(function(mutations) { 2054 mutations.forEach(function(mut){ 2055 if (mut.type=="attributes") { 2056 return ($("body").hasClass("modal-open") && $("body").hasClass("modal-dialog") && !$.contains($('.modal-dialog')[0],self.doc[0])) ? self.hide() : self.show(); // Support for Bootstrap modal; Added check if the nice scroll element is inside a modal 2057 } 2058 }); 2059 // if (document.body.scrollHeight!=self.page.maxh) return self.lazyResize(30); 2060 if (self.me.clientWidth!=self.page.width || self.me.clientHeight!=self.page.height) return self.lazyResize(30); 2061 }); 2062 self.observerbody.observe(document.body, { 2063 childList: true, 2064 subtree: true, 2065 characterData: false, 2066 attributes: true, 2067 attributeFilter: ['class'] 2068 }); 2069 } 2070 2071 if (!self.ispage && !self.haswrapper) { 2072 // redesigned MutationObserver for Chrome18+/Firefox14+/iOS6+ with support for: remove div, add/remove content 2073 if (ClsMutationObserver !== false) { 2074 self.observer = new ClsMutationObserver(function(mutations) { 2075 mutations.forEach(self.onAttributeChange); 2076 }); 2077 self.observer.observe(self.win[0], { 2078 childList: true, 2079 characterData: false, 2080 attributes: true, 2081 subtree: false 2082 }); 2083 self.observerremover = new ClsMutationObserver(function(mutations) { 2084 mutations.forEach(function(mo) { 2085 if (mo.removedNodes.length > 0) { 2086 for (var dd in mo.removedNodes) { 2087 if (!!self && (mo.removedNodes[dd] == self.win[0])) return self.remove(); 2088 } 2089 } 2090 }); 2091 }); 2092 self.observerremover.observe(self.win[0].parentNode, { 2093 childList: true, 2094 characterData: false, 2095 attributes: false, 2096 subtree: false 2097 }); 2098 } else { 2099 self.bind(self.win, (cap.isie && !cap.isie9) ? "propertychange" : "DOMAttrModified", self.onAttributeChange); 2100 if (cap.isie9) self.win[0].attachEvent("onpropertychange", self.onAttributeChange); //IE9 DOMAttrModified bug 2101 self.bind(self.win, "DOMNodeRemoved", function(e) { 2102 if (e.target == self.win[0]) self.remove(); 2103 }); 2104 } 2105 } 2106 2107 // 2108 2109 if (!self.ispage && self.opt.boxzoom) self.bind(window, "resize", self.resizeZoom); 2110 if (self.istextarea) { 2111 self.bind(self.win, "keydown", self.lazyResize); 2112 self.bind(self.win, "mouseup", self.lazyResize); 2113 } 2114 2115 // self.checkrtlmode = true; 2116 self.lazyResize(30); 2117 2118 } 2119 2120 if (this.doc[0].nodeName == 'IFRAME') { 2121 var oniframeload = function() { 2122 self.iframexd = false; 2123 var doc; 2124 try { 2125 doc = 'contentDocument' in this ? this.contentDocument : this.contentWindow.document; 2126 var a = doc.domain; 2127 } catch (e) { 2128 self.iframexd = true; 2129 doc = false; 2130 } 2131 2132 if (self.iframexd) { 2133 if ("console" in window) console.log('NiceScroll error: policy restriced iframe'); 2134 return true; //cross-domain - I can't manage this 2135 } 2136 2137 self.forcescreen = true; 2138 2139 if (self.isiframe) { 2140 self.iframe = { 2141 "doc": $(doc), 2142 "html": self.doc.contents().find('html')[0], 2143 "body": self.doc.contents().find('body')[0] 2144 }; 2145 self.getContentSize = function() { 2146 return { 2147 w: Math.max(self.iframe.html.scrollWidth, self.iframe.body.scrollWidth), 2148 h: Math.max(self.iframe.html.scrollHeight, self.iframe.body.scrollHeight) 2149 }; 2150 }; 2151 self.docscroll = $(self.iframe.body); //$(this.contentWindow); 2152 } 2153 2154 if (!cap.isios && self.opt.iframeautoresize && !self.isiframe) { 2155 self.win.scrollTop(0); // reset position 2156 self.doc.height(""); //reset height to fix browser bug 2157 var hh = Math.max(doc.getElementsByTagName('html')[0].scrollHeight, doc.body.scrollHeight); 2158 self.doc.height(hh); 2159 } 2160 self.lazyResize(30); 2161 2162 if (cap.isie7) self.css($(self.iframe.html), _scrollyhidden); 2163 self.css($(self.iframe.body), _scrollyhidden); 2164 2165 if (cap.isios && self.haswrapper) { 2166 self.css($(doc.body), {
2167 '-webkit-transform': 'translate3d(0,0,0)' 2168 }); // avoid iFrame content clipping - thanks to http://blog.derraab.com/2012/04/02/avoid-iframe-content-clipping-with-css-transform-on-ios/ 2169 } 2170 2171 if ('contentWindow' in this) { 2172 self.bind(this.contentWindow, "scroll", self.onscroll); //IE8 & minor 2173 } else { 2174 self.bind(doc, "scroll", self.onscroll); 2175 } 2176 2177 if (self.opt.enablemousewheel) { 2178 self.mousewheel(doc, self.onmousewheel); 2179 } 2180 2181 if (self.opt.enablekeyboard) self.bind(doc, (cap.isopera) ? "keypress" : "keydown", self.onkeypress); 2182 2183 if (cap.cantouch || self.opt.touchbehavior) { 2184 self.bind(doc, "mousedown", self.ontouchstart); 2185 self.bind(doc, "mousemove", function(e) { 2186 return self.ontouchmove(e, true); 2187 }); 2188 if (self.opt.grabcursorenabled && cap.cursorgrabvalue) self.css($(doc.body), { 2189 'cursor': cap.cursorgrabvalue 2190 }); 2191 } 2192 2193 self.bind(doc, "mouseup", self.ontouchend); 2194 2195 if (self.zoom) { 2196 if (self.opt.dblclickzoom) self.bind(doc, 'dblclick', self.doZoom); 2197 if (self.ongesturezoom) self.bind(doc, "gestureend", self.ongesturezoom); 2198 } 2199 }; 2200 2201 if (this.doc[0].readyState && this.doc[0].readyState == "complete") { 2202 setTimeout(function() { 2203 oniframeload.call(self.doc[0], false); 2204 }, 500); 2205 } 2206 self.bind(this.doc, "load", oniframeload); 2207 2208 } 2209 2210 }; 2211 2212 this.showCursor = function(py, px) { 2213 if (self.cursortimeout) { 2214 clearTimeout(self.cursortimeout); 2215 self.cursortimeout = 0; 2216 } 2217 if (!self.rail) return; 2218 if (self.autohidedom) { 2219 self.autohidedom.stop().css({ 2220 opacity: self.opt.cursoropacitymax 2221 }); 2222 self.cursoractive = true; 2223 } 2224 2225 if (!self.rail.drag || self.rail.drag.pt != 1) { 2226 if (py !== undefined && py !== false) { 2227 self.scroll.y = Math.round(py * 1 / self.scrollratio.y); 2228 } 2229 if (px !== undefined) { 2230 self.scroll.x = Math.round(px * 1 / self.scrollratio.x); 2231 } 2232 } 2233 2234 self.cursor.css({ 2235 height: self.cursorheight, 2236 top: self.scroll.y 2237 }); 2238 if (self.cursorh) { 2239 var lx = (self.hasreversehr) ? self.scrollvaluemaxw-self.scroll.x : self.scroll.x; 2240 (!self.rail.align && self.rail.visibility) ? self.cursorh.css({ 2241 width: self.cursorwidth, 2242 left: lx + self.rail.width 2243 }): self.cursorh.css({ 2244 width: self.cursorwidth, 2245 left: lx 2246 }); 2247 self.cursoractive = true; 2248 } 2249 2250 if (self.zoom) self.zoom.stop().css({ 2251 opacity: self.opt.cursoropacitymax 2252 }); 2253 }; 2254 2255 this.hideCursor = function(tm) { 2256 if (self.cursortimeout) return; 2257 if (!self.rail) return; 2258 if (!self.autohidedom) return; 2259 if (self.hasmousefocus && self.opt.autohidemode == "leave") return; 2260 self.cursortimeout = setTimeout(function() { 2261 if (!self.rail.active || !self.showonmouseevent) { 2262 self.autohidedom.stop().animate({ 2263 opacity: self.opt.cursoropacitymin 2264 }); 2265 if (self.zoom) self.zoom.stop().animate({ 2266 opacity: self.opt.cursoropacitymin 2267 }); 2268 self.cursoractive = false; 2269 } 2270 self.cursortimeout = 0; 2271 }, tm || self.opt.hidecursordelay); 2272 }; 2273 2274 this.noticeCursor = function(tm, py, px) { 2275 self.showCursor(py, px); 2276 if (!self.rail.active) self.hideCursor(tm); 2277 }; 2278 2279 this.getContentSize = 2280 (self.ispage) ? 2281 function() { 2282 return { 2283 w: Math.max(document.body.scrollWidth, document.documentElement.scrollWidth), 2284 h: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) 2285 }; 2286 } : (self.haswrapper) ? 2287 function() { 2288 return { 2289 w: self.doc.outerWidth() + parseInt(self.win.css('paddingLeft')) + parseInt(self.win.css('paddingRight')), 2290 h: self.doc.outerHeight() + parseInt(self.win.css('paddingTop')) + parseInt(self.win.css('paddingBottom')) 2291 }; 2292 } : function() { 2293 return { 2294 w: self.docscroll[0].scrollWidth, 2295 h: self.docscroll[0].scrollHeight 2296 }; 2297 }; 2298 2299 this.onResize = function(e, page) { 2300 2301 if (!self || !self.win) return false; 2302 2303 if (!self.haswrapper && !self.ispage) { 2304 if (self.win.css('display') == 'none') { 2305 if (self.visibility) self.hideRail().hideRailHr(); 2306 return false; 2307 } else { 2308 if (!self.hidden && !self.visibility) self.showRail().showRailHr(); 2309 } 2310 } 2311 2312 var premaxh = self.page.maxh;
2313 var premaxw = self.page.maxw; 2314 2315 var preview = { 2316 h: self.view.h, 2317 w: self.view.w 2318 }; 2319 2320 self.view = { 2321 w: (self.ispage) ? self.win.width() : parseInt(self.win[0].clientWidth), 2322 h: (self.ispage) ? self.win.height() : parseInt(self.win[0].clientHeight) 2323 }; 2324 2325 self.page = (page) ? page : self.getContentSize(); 2326 2327 self.page.maxh = Math.max(0, self.page.h - self.view.h); 2328 self.page.maxw = Math.max(0, self.page.w - self.view.w); 2329 2330 if ((self.page.maxh == premaxh) && (self.page.maxw == premaxw) && (self.view.w == preview.w) && (self.view.h == preview.h)) { 2331 // test position 2332 if (!self.ispage) { 2333 var pos = self.win.offset(); 2334 if (self.lastposition) { 2335 var lst = self.lastposition; 2336 if ((lst.top == pos.top) && (lst.left == pos.left)) return self; //nothing to do 2337 } 2338 self.lastposition = pos; 2339 } else { 2340 return self; //nothing to do 2341 } 2342 } 2343 2344 if (self.page.maxh == 0) { 2345 self.hideRail(); 2346 self.scrollvaluemax = 0; 2347 self.scroll.y = 0; 2348 self.scrollratio.y = 0; 2349 self.cursorheight = 0; 2350 self.setScrollTop(0); 2351 if (self.rail) self.rail.scrollable = false; 2352 } else { 2353 self.page.maxh -= (self.opt.railpadding.top + self.opt.railpadding.bottom); //** 2354 self.rail.scrollable = true; 2355 } 2356 2357 if (self.page.maxw == 0) { 2358 self.hideRailHr(); 2359 self.scrollvaluemaxw = 0; 2360 self.scroll.x = 0; 2361 self.scrollratio.x = 0; 2362 self.cursorwidth = 0; 2363 self.setScrollLeft(0); 2364 if (self.railh) { 2365 self.railh.scrollable = false; 2366 } 2367 } else { 2368 self.page.maxw -= (self.opt.railpadding.left + self.opt.railpadding.right); //** 2369 if (self.railh) self.railh.scrollable = (self.opt.horizrailenabled); 2370 } 2371 2372 self.railslocked = (self.locked) || ((self.page.maxh == 0) && (self.page.maxw == 0)); 2373 if (self.railslocked) { 2374 if (!self.ispage) self.updateScrollBar(self.view); 2375 return false; 2376 } 2377 2378 if (!self.hidden && !self.visibility) { 2379 self.showRail().showRailHr(); 2380 } 2381 else if (self.railh && (!self.hidden && !self.railh.visibility)) self.showRailHr(); 2382 2383 if (self.istextarea && self.win.css('resize') && self.win.css('resize') != 'none') self.view.h -= 20; 2384 2385 self.cursorheight = Math.min(self.view.h, Math.round(self.view.h * (self.view.h / self.page.h))); 2386 self.cursorheight = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight, self.cursorheight); 2387 2388 self.cursorwidth = Math.min(self.view.w, Math.round(self.view.w * (self.view.w / self.page.w))); 2389 self.cursorwidth = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight, self.cursorwidth); 2390 2391 self.scrollvaluemax = self.view.h - self.cursorheight - self.cursor.hborder - (self.opt.railpadding.top + self.opt.railpadding.bottom); //** 2392 2393 if (self.railh) { 2394 self.railh.width = (self.page.maxh > 0) ? (self.view.w - self.rail.width) : self.view.w; 2395 self.scrollvaluemaxw = self.railh.width - self.cursorwidth - self.cursorh.wborder - (self.opt.railpadding.left + self.opt.railpadding.right); //** 2396 } 2397 2398 /* 2399 if (self.checkrtlmode&&self.railh) { 2400 self.checkrtlmode = false; 2401 if (self.opt.rtlmode&&self.scroll.x==0) self.setScrollLeft(self.page.maxw); 2402 } 2403*/ 2404 2405 if (!self.ispage) self.updateScrollBar(self.view); 2406 2407 self.scrollratio = { 2408 x: (self.page.maxw / self.scrollvaluemaxw), 2409 y: (self.page.maxh / self.scrollvaluemax) 2410 }; 2411 2412 var sy = self.getScrollTop(); 2413 if (sy > self.page.maxh) { 2414 self.doScrollTop(self.page.maxh); 2415 } else { 2416 self.scroll.y = Math.round(self.getScrollTop() * (1 / self.scrollratio.y)); 2417 self.scroll.x = Math.round(self.getScrollLeft() * (1 / self.scrollratio.x)); 2418 if (self.cursoractive) self.noticeCursor(); 2419 } 2420 2421 if (self.scroll.y && (self.getScrollTop() == 0)) self.doScrollTo(Math.floor(self.scroll.y * self.scrollratio.y)); 2422 2423 return self; 2424 }; 2425 2426 this.resize = self.onResize; 2427 2428 this.hlazyresize = 0; 2429 2430 this.lazyResize = function(tm) { // event debounce 2431/* 2432 tm = (isNaN(tm)) ? 30 : tm; 2433 self.debounced('resize', self.resize, tm); 2434*/ 2435 2436// if (!self.haswrapper&&self.opt.autohidemode!==false) self.hide(); 2437 if (!self.haswrapper) self.hide(); 2438 if (self.hlazyresize) clearTimeout(self.hlazyresize); 2439 self.hlazyresize = setTimeout(function(){ 2440 self && self.show().resize(); 2441 },240); 2442 2443 return self; 2444 }; 2445 2446 // modified by MDN https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/wheel 2447 function _modernWheelEvent(dom, name, fn, bubble) { 2448 self._bind(dom, name, function(e) { 2449 var e = (e) ? e : window.event; 2450 var event = { 2451 original: e, 2452 target: e.target || e.srcElement, 2453 type: "wheel", 2454 deltaMode: e.type == "MozMousePixelScroll" ? 0 : 1, 2455 deltaX: 0, 2456 deltaZ: 0, 2457 preventDefault: function() { 2458 e.preventDefault ? e.preventDefault() : e.returnValue = false; 2459 return false; 2460 }, 2461 stopImmediatePropagation: function() { 2462 (e.stopImmediatePropagation) ? e.stopImmediatePropagation(): e.cancelBubble = true; 2463 } 2464 }; 2465 2466 if (name == "mousewheel") {
2467 e.wheelDeltaX && (event.deltaX = -1 / 40 * e.wheelDeltaX); 2468 e.wheelDeltaY && (event.deltaY = -1 / 40 * e.wheelDeltaY); 2469 !event.deltaY && !event.deltaX && (event.deltaY = -1 / 40 * e.wheelDelta); 2470 } else { 2471 event.deltaY = e.detail; 2472 } 2473 2474 return fn.call(dom, event); 2475 }, bubble); 2476 } 2477 2478 2479 2480 this.jqbind = function(dom, name, fn) { // use jquery bind for non-native events (mouseenter/mouseleave) 2481 self.events.push({ 2482 e: dom, 2483 n: name, 2484 f: fn, 2485 q: true 2486 }); 2487 $(dom).bind(name, fn); 2488 }; 2489 2490 this.mousewheel = function(dom, fn, bubble) { // bind mousewheel 2491 var el = ("jquery" in dom) ? dom[0] : dom; 2492 if ("onwheel" in document.createElement("div")) { // Modern browsers support "wheel" 2493 self._bind(el, "wheel", fn, bubble || false); 2494 } else { 2495 var wname = (document.onmousewheel !== undefined) ? "mousewheel" : "DOMMouseScroll"; // older Webkit+IE support or older Firefox 2496 _modernWheelEvent(el, wname, fn, bubble || false); 2497 if (wname == "DOMMouseScroll") _modernWheelEvent(el, "MozMousePixelScroll", fn, bubble || false); // Firefox legacy 2498 } 2499 }; 2500 2501 if (cap.haseventlistener) { // W3C standard event model 2502 2503 this.bind = function(dom, name, fn, bubble) { // W3C 2504 var el = ("jquery" in dom) ? dom[0] : dom; 2505 self._bind(el, name, fn, bubble || false); 2506 }; 2507 2508 this._bind = function(el, name, fn, bubble) { // primitive bind 2509 self.events.push({ 2510 e: el, 2511 n: name, 2512 f: fn, 2513 b: bubble, 2514 q: false 2515 }); 2516 el.addEventListener(name, fn, bubble || false); 2517 }; 2518 this.cancelEvent = function(e) { 2519 if (!e) return false; 2520 var e = (e.original) ? e.original : e; 2521 if (e.cancelable) e.preventDefault(); 2522 e.stopPropagation(); 2523 if (e.preventManipulation) e.preventManipulation(); //IE10 2524 return false; 2525 }; 2526 this.stopPropagation = function(e) { 2527 if (!e) return false; 2528 var e = (e.original) ? e.original : e; 2529 e.stopPropagation(); 2530 return false; 2531 }; 2532 this._unbind = function(el, name, fn, bub) { // primitive unbind 2533 el.removeEventListener(name, fn, bub); 2534 }; 2535 } else { // old IE model 2536 2537 this.bind = function(dom, name, fn, bubble) { // legacy IE 2538 var el = ("jquery" in dom) ? dom[0] : dom; 2539 self._bind(el, name, function(e) { 2540 e = e || window.event || false; 2541 if (e && e.srcElement) { 2542 e.target = e.srcElement; 2543 } 2544 if (!("pageY" in e)) { 2545 e.pageX = e.clientX + document.documentElement.scrollLeft; 2546 e.pageY = e.clientY + document.documentElement.scrollTop; 2547 } 2548 return ((fn.call(el, e) === false) || bubble === false) ? self.cancelEvent(e) : true; 2549 }); 2550 }; 2551 2552 this._bind = function(el, name, fn, bubble) { // primitive bind 2553 self.events.push({ 2554 e: el, 2555 n: name, 2556 f: fn, 2557 b: bubble, 2558 q: false 2559 }); 2560 if (el.attachEvent) { 2561 el.attachEvent("on" + name, fn); 2562 } else { 2563 el["on" + name] = fn; 2564 } 2565 }; 2566 // Thanks to http://www.switchonthecode.com !! 2567 this.cancelEvent = function(e) { 2568 var e = window.event || false; 2569 if (!e) return false; 2570 e.cancelBubble = true; 2571 e.cancel = true; 2572 e.returnValue = false; 2573 return false; 2574 }; 2575 this.stopPropagation = function(e) { 2576 var e = window.event || false; 2577 if (!e) return false; 2578 e.cancelBubble = true; 2579 return false; 2580 }; 2581 this._unbind = function(el, name, fn, bub) { // primitive unbind IE old 2582 if (el.detachEvent) { 2583 el.detachEvent('on' + name, fn); 2584 } else { 2585 el['on' + name] = false; 2586 } 2587 }; 2588 } 2589 2590 this.unbindAll = function() { 2591 for (var a = 0; a < self.events.length; a++) { 2592 var r = self.events[a]; 2593 (r.q) ? r.e.unbind(r.n, r.f): self._unbind(r.e, r.n, r.f, r.b); 2594 } 2595 }; 2596 2597 this.showRail = function() { 2598 if ((self.page.maxh != 0) && (self.ispage || self.win.css('display') != 'none')) { 2599 self.visibility = true; 2600 self.rail.visibility = true; 2601 self.rail.css('display', 'block'); 2602 } 2603 return self; 2604 }; 2605 2606 this.showRailHr = function() { 2607 if (!self.railh) return self; 2608 if ((self.page.maxw != 0) && (self.ispage || self.win.css('display') != 'none')) { 2609 self.railh.visibility = true; 2610 self.railh.css('display', 'block'); 2611 } 2612 return self; 2613 }; 2614 2615 this.hideRail = function() { 2616 self.visibility = false; 2617 self.rail.visibility = false; 2618 self.rail.css('display', 'none'); 2619 return self; 2620 }; 2621 2622 this.hideRailHr = function() { 2623 if (!self.railh) return self; 2624 self.railh.visibility = false; 2625 self.railh.css('display', 'none'); 2626 return self; 2627 }; 2628 2629 this.show = function() { 2630 self.hidden = false; 2631 self.railslocked = false; 2632 return self.showRail().showRailHr(); 2633 }; 2634 2635 this.hide = function() { 2636 self.hidden = true; 2637 self.railslocked = true; 2638 return self.hideRail().hideRailHr(); 2639 }; 2640 2641 this.toggle = function() { 2642 return (self.hidden) ? self.show() : self.hide(); 2643 }; 2644 2645 this.remove = function() { 2646 self.stop(); 2647 if (self.cursortimeout) clearTimeout(self.cursortimeout); 2648// if (self.debouncedelayed) clearTimeout(self.debouncedelayed); 2649 for(var n in self.delaylist) if (self.delaylist[n]) clearAnimationFrame(self.delaylist[n].h); 2650 self.doZoomOut(); 2651 self.unbindAll(); 2652 2653 if (cap.isie9) self.win[0].detachEvent("onpropertychange", self.onAttributeChange); //IE9 DOMAttrModified bug 2654 2655 if (self.observer !== false) self.observer.disconnect(); 2656 if (self.observerremover !== false) self.observerremover.disconnect(); 2657 if (self.observerbody !== false) self.observerbody.disconnect(); 2658 2659 self.events = null; 2660 2661 if (self.cursor) { 2662 self.cursor.remove(); 2663 } 2664 if (self.cursorh) { 2665 self.cursorh.remove(); 2666 } 2667 if (self.rail) { 2668 self.rail.remove(); 2669 } 2670 if (self.railh) { 2671 self.railh.remove(); 2672 } 2673 if (self.zoom) { 2674 self.zoom.remove(); 2675 } 2676 for (var a = 0; a < self.saved.css.length; a++) { 2677 var d = self.saved.css[a]; 2678 d[0].css(d[1], (d[2] === undefined) ? '' : d[2]); 2679 } 2680 self.saved = false; 2681 self.me.data('__nicescroll', ''); //erase all traces 2682 2683 // memory leak fixed by GianlucaGuarini - thanks a lot! 2684 // remove the current nicescroll from the $.nicescroll array & normalize array 2685 var lst = $.nicescroll; 2686 lst.each(function(i) { 2687 if (!this) return; 2688 if (this.id === self.id) { 2689 delete lst[i]; 2690 for (var b = ++i; b < lst.length; b++, i++) lst[i] = lst[b]; 2691 lst.length--; 2692 if (lst.length) delete lst[lst.length]; 2693 } 2694 }); 2695 2696 for (var i in self) { 2697 self[i] = null; 2698 delete self[i]; 2699 } 2700 2701 self = null; 2702 2703 }; 2704 2705 this.scrollstart = function(fn) { 2706 this.onscrollstart = fn; 2707 return self; 2708 }; 2709 this.scrollend = function(fn) { 2710 this.onscrollend = fn; 2711 return self; 2712 }; 2713 this.scrollcancel = function(fn) { 2714 this.onscrollcancel = fn; 2715 return self; 2716 }; 2717 2718 this.zoomin = function(fn) { 2719 this.onzoomin = fn; 2720 return self; 2721 }; 2722 this.zoomout = function(fn) { 2723 this.onzoomout = fn; 2724 return self; 2725 }; 2726 2727 this.isScrollable = function(e) { 2728 var dom = (e.target) ? e.target : e; 2729 if (dom.nodeName == 'OPTION') return true; 2730 while (dom && (dom.nodeType == 1) && (dom !== this.me[0]) && !(/^BODY|HTML/.test(dom.nodeName))) { 2731 var dd = $(dom); 2732 var ov = dd.css('overflowY') || dd.css('overflowX') || dd.css('overflow') || ''; 2733 if (/scroll|auto/.test(ov)) return (dom.clientHeight != dom.scrollHeight); 2734 dom = (dom.parentNode) ? dom.parentNode : false; 2735 } 2736 return false; 2737 }; 2738 2739 this.getViewport = function(me) { 2740 var dom = (me && me.parentNode) ? me.parentNode : false; 2741 while (dom && (dom.nodeType == 1) && !(/^BODY|HTML/.test(dom.nodeName))) { 2742 var dd = $(dom); 2743 if (/fixed|absolute/.test(dd.css("position"))) return dd; 2744 var ov = dd.css('overflowY') || dd.css('overflowX') || dd.css('overflow') || ''; 2745 if ((/scroll|auto/.test(ov)) && (dom.clientHeight != dom.scrollHeight)) return dd; 2746 if (dd.getNiceScroll().length > 0) return dd; 2747 dom = (dom.parentNode) ? dom.parentNode : false; 2748 } 2749 return false; //(dom) ? $(dom) : false; 2750 }; 2751 2752 this.triggerScrollEnd = function() { 2753 if (!self.onscrollend) return; 2754 2755 var px = self.getScrollLeft(); 2756 var py = self.getScrollTop(); 2757 2758 var info = { 2759 type: "scrollend", 2760 current: { 2761 x: px, 2762 y: py 2763 }, 2764 end: { 2765 x: px, 2766 y: py 2767 } 2768 }; 2769 self.onscrollend.call(self, info); 2770 }; 2771 2772 function execScrollWheel(e, hr, chkscroll) { 2773 var px, py; 2774 2775 if (e.deltaMode == 0) { // PIXEL 2776 px = -Math.floor(e.deltaX * (self.opt.mousescrollstep / (18 * 3))); 2777 py = -Math.floor(e.deltaY * (self.opt.mousescrollstep / (18 * 3))); 2778 } else if (e.deltaMode == 1) { // LINE 2779 px = -Math.floor(e.deltaX * self.opt.mousescrollstep); 2780 py = -Math.floor(e.deltaY * self.opt.mousescrollstep); 2781 } 2782 2783 if (hr && self.opt.oneaxismousemode && (px == 0) && py) { // classic vertical-only mousewheel + browser with x/y support 2784 px = py; 2785 py = 0; 2786 2787 if (chkscroll) { 2788 var hrend = (px < 0) ? (self.getScrollLeft() >= self.page.maxw) : (self.getScrollLeft() <= 0); 2789 if (hrend) { // preserve vertical scrolling 2790 py = px; 2791 px = 0; 2792 } 2793 } 2794 2795 } 2796 2797 // invert horizontal direction for rtl mode 2798 if (self.isrtlmode) px = -px; 2799 2800 if (px) { 2801 if (self.scrollmom) { 2802 self.scrollmom.stop(); 2803 } 2804 self.lastdeltax += px; 2805 self.debounced("mousewheelx", function() { 2806 var dt = self.lastdeltax; 2807 self.lastdeltax = 0; 2808 if (!self.rail.drag) { 2809 self.doScrollLeftBy(dt); 2810 } 2811 }, 15); 2812 } 2813 if (py) { 2814 if (self.opt.nativeparentscrolling && chkscroll && !self.ispage && !self.zoomactive) { 2815 if (py < 0) { 2816 if (self.getScrollTop() >= self.page.maxh) return true; 2817 } else { 2818 if (self.getScrollTop() <= 0) return true; 2819 } 2820 } 2821 if (self.scrollmom) { 2822 self.scrollmom.stop(); 2823 } 2824 self.lastdeltay += py; 2825// self.debounced("mousewheely", function() { 2826 self.synched("mousewheely", function() { 2827 var dt = self.lastdeltay; 2828 self.lastdeltay = 0; 2829 if (!self.rail.drag) { 2830 self.doScrollBy(dt); 2831 } 2832 }, 15); 2833 } 2834 2835 e.stopImmediatePropagation(); 2836 return e.preventDefault(); 2837 } 2838 2839 this.onmousewheel = function(e) { 2840 if (self.wheelprevented) return; 2841 if (self.railslocked) { 2842 self.debounced("checkunlock", self.resize, 250); 2843 return true; 2844 } 2845 if (self.rail.drag) return self.cancelEvent(e); 2846 2847 if (self.opt.oneaxismousemode == "auto" && e.deltaX != 0) self.opt.oneaxismousemode = false; // check two-axis mouse support (not very elegant) 2848 2849 if (self.opt.oneaxismousemode && e.deltaX == 0) { 2850 if (!self.rail.scrollable) { 2851 if (self.railh && self.railh.scrollable) { 2852 return self.onmousewheelhr(e); 2853 } else { 2854 return true; 2855 } 2856 } 2857 } 2858 2859 var nw = +(new Date()); 2860 var chk = false; 2861 if (self.opt.preservenativescrolling && ((self.checkarea + 600) < nw)) { 2862 self.nativescrollingarea = self.isScrollable(e); 2863 chk = true; 2864 } 2865 self.checkarea = nw; 2866 if (self.nativescrollingarea) return true; // this isn't my business 2867 var ret = execScrollWheel(e, false, chk); 2868 if (ret) self.checkarea = 0; 2869 return ret; 2870 }; 2871 2872 this.onmousewheelhr = function(e) { 2873 if (self.wheelprevented) return; 2874 if (self.railslocked || !self.railh.scrollable) return true; 2875 if (self.rail.drag) return self.cancelEvent(e); 2876 2877 var nw = +(new Date()); 2878 var chk = false; 2879 if (self.opt.preservenativescrolling && ((self.checkarea + 600) < nw)) { 2880 self.nativescrollingarea = self.isScrollable(e); 2881 chk = true; 2882 } 2883 self.checkarea = nw; 2884 if (self.nativescrollingarea) return true; // this isn't my business 2885 if (self.railslocked) return self.cancelEvent(e); 2886 2887 return execScrollWheel(e, true, chk); 2888 }; 2889 2890 this.stop = function() { 2891 self.cancelScroll(); 2892 if (self.scrollmon) self.scrollmon.stop(); 2893 self.cursorfreezed = false; 2894 self.scroll.y = Math.round(self.getScrollTop() * (1 / self.scrollratio.y)); 2895 self.noticeCursor(); 2896 return self; 2897 }; 2898 2899 this.getTransitionSpeed = function(dif) { 2900 var sp = Math.round(self.opt.scrollspeed * 10); 2901 var ex = Math.min(sp, Math.round((dif / 20) * self.opt.scrollspeed)); 2902 return (ex > 20) ? ex : 0; 2903 }; 2904 2905 if (!self.opt.smoothscroll) { 2906 this.doScrollLeft = function(x, spd) { //direct 2907 var y = self.getScrollTop(); 2908 self.doScrollPos(x, y, spd); 2909 }; 2910 this.doScrollTop = function(y, spd) { //direct 2911 var x = self.getScrollLeft(); 2912 self.doScrollPos(x, y, spd); 2913 }; 2914 this.doScrollPos = function(x, y, spd) { //direct 2915 var nx = (x > self.page.maxw) ? self.page.maxw : x; 2916 if (nx < 0) nx = 0; 2917 var ny = (y > self.page.maxh) ? self.page.maxh : y; 2918 if (ny < 0) ny = 0; 2919 self.synched('scroll', function() { 2920 self.setScrollTop(ny); 2921 self.setScrollLeft(nx); 2922 }); 2923 }; 2924 this.cancelScroll = function() {}; // direct 2925 } else if (self.ishwscroll && cap.hastransition && self.opt.usetransition && !!self.opt.smoothscroll) { 2926 this.prepareTransition = function(dif, istime) { 2927 var ex = (istime) ? ((dif > 20) ? dif : 0) : self.getTransitionSpeed(dif); 2928 var trans = (ex) ? cap.prefixstyle + 'transform ' + ex + 'ms ease-out' : ''; 2929 if (!self.lasttransitionstyle || self.lasttransitionstyle != trans) { 2930 self.lasttransitionstyle = trans; 2931 self.doc.css(cap.transitionstyle, trans); 2932 } 2933 return ex; 2934 }; 2935 2936 this.doScrollLeft = function(x, spd) { //trans 2937 var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop(); 2938 self.doScrollPos(x, y, spd); 2939 }; 2940 2941 this.doScrollTop = function(y, spd) { //trans 2942 var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft(); 2943 self.doScrollPos(x, y, spd); 2944 }; 2945 2946 this.doScrollPos = function(x, y, spd) { //trans 2947 2948 var py = self.getScrollTop(); 2949 var px = self.getScrollLeft(); 2950 2951 if (((self.newscrolly - py) * (y - py) < 0) || ((self.newscrollx - px) * (x - px) < 0)) self.cancelScroll(); //inverted movement detection 2952 2953 if (self.opt.bouncescroll == false) { 2954 if (y < 0) y = 0; 2955 else if (y > self.page.maxh) y = self.page.maxh;
2956 if (x < 0) x = 0; 2957 else if (x > self.page.maxw) x = self.page.maxw; 2958 } 2959 2960 if (self.scrollrunning && x == self.newscrollx && y == self.newscrolly) return false; 2961 2962 self.newscrolly = y; 2963 self.newscrollx = x; 2964 2965 self.newscrollspeed = spd || false; 2966 2967 if (self.timer) return false; 2968 2969 self.timer = setTimeout(function() { 2970 2971 var top = self.getScrollTop(); 2972 var lft = self.getScrollLeft(); 2973 2974 var dst = {}; 2975 dst.x = x - lft; 2976 dst.y = y - top; 2977 dst.px = lft; 2978 dst.py = top; 2979 2980 var dd = Math.round(Math.sqrt(Math.pow(dst.x, 2) + Math.pow(dst.y, 2))); 2981 var ms = (self.newscrollspeed && self.newscrollspeed > 1) ? self.newscrollspeed : self.getTransitionSpeed(dd); 2982 if (self.newscrollspeed && self.newscrollspeed <= 1) ms *= self.newscrollspeed; 2983 2984 self.prepareTransition(ms, true); 2985 2986 if (self.timerscroll && self.timerscroll.tm) clearInterval(self.timerscroll.tm); 2987 2988 if (ms > 0) { 2989 2990 if (!self.scrollrunning && self.onscrollstart) { 2991 var info = { 2992 "type": "scrollstart", 2993 "current": { 2994 "x": lft, 2995 "y": top 2996 }, 2997 "request": { 2998 "x": x, 2999 "y": y 3000 }, 3001 "end": { 3002 "x": self.newscrollx, 3003 "y": self.newscrolly 3004 }, 3005 "speed": ms 3006 }; 3007 self.onscrollstart.call(self, info); 3008 } 3009 3010 if (cap.transitionend) { 3011 if (!self.scrollendtrapped) { 3012 self.scrollendtrapped = true; 3013 self.bind(self.doc, cap.transitionend, self.onScrollTransitionEnd, false); //I have got to do something usefull!! 3014 } 3015 } else { 3016 if (self.scrollendtrapped) clearTimeout(self.scrollendtrapped); 3017 self.scrollendtrapped = setTimeout(self.onScrollTransitionEnd, ms); // simulate transitionend event 3018 } 3019 3020 var py = top; 3021 var px = lft; 3022 self.timerscroll = { 3023 bz: new BezierClass(py, self.newscrolly, ms, 0, 0, 0.58, 1), 3024 bh: new BezierClass(px, self.newscrollx, ms, 0, 0, 0.58, 1) 3025 }; 3026 if (!self.cursorfreezed) self.timerscroll.tm = setInterval(function() { 3027 self.showCursor(self.getScrollTop(), self.getScrollLeft()); 3028 }, 60); 3029 3030 } 3031 3032 self.synched("doScroll-set", function() { 3033 self.timer = 0; 3034 if (self.scrollendtrapped) self.scrollrunning = true; 3035 self.setScrollTop(self.newscrolly); 3036 self.setScrollLeft(self.newscrollx); 3037 if (!self.scrollendtrapped) self.onScrollTransitionEnd(); 3038 }); 3039 3040 3041 }, 50); 3042 3043 }; 3044 3045 this.cancelScroll = function() { 3046 if (!self.scrollendtrapped) return true; 3047 var py = self.getScrollTop(); 3048 var px = self.getScrollLeft(); 3049 self.scrollrunning = false; 3050 if (!cap.transitionend) clearTimeout(cap.transitionend); 3051 self.scrollendtrapped = false; 3052 self._unbind(self.doc[0], cap.transitionend, self.onScrollTransitionEnd); 3053 self.prepareTransition(0); 3054 self.setScrollTop(py); // fire event onscroll 3055 if (self.railh) self.setScrollLeft(px); 3056 if (self.timerscroll && self.timerscroll.tm) clearInterval(self.timerscroll.tm); 3057 self.timerscroll = false; 3058 3059 self.cursorfreezed = false; 3060 3061 self.showCursor(py, px); 3062 return self; 3063 }; 3064 this.onScrollTransitionEnd = function() { 3065 if (self.scrollendtrapped) self._unbind(self.doc[0], cap.transitionend, self.onScrollTransitionEnd); 3066 self.scrollendtrapped = false; 3067 self.prepareTransition(0); 3068 if (self.timerscroll && self.timerscroll.tm) clearInterval(self.timerscroll.tm); 3069 self.timerscroll = false; 3070 var py = self.getScrollTop(); 3071 var px = self.getScrollLeft(); 3072 self.setScrollTop(py); // fire event onscroll 3073 if (self.railh) self.setScrollLeft(px);
3073 // fire event onscroll left 3074 3075 self.noticeCursor(false, py, px); 3076 3077 self.cursorfreezed = false; 3078 3079 if (py < 0) py = 0; 3080 else if (py > self.page.maxh) py = self.page.maxh; 3081 if (px < 0) px = 0; 3082 else if (px > self.page.maxw) px = self.page.maxw; 3083 if ((py != self.newscrolly) || (px != self.newscrollx)) return self.doScrollPos(px, py, self.opt.snapbackspeed); 3084 3085 if (self.onscrollend && self.scrollrunning) { 3086 self.triggerScrollEnd(); 3087 } 3088 self.scrollrunning = false; 3089 3090 }; 3091 3092 } else { 3093 3094 this.doScrollLeft = function(x, spd) { //no-trans 3095 var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop(); 3096 self.doScrollPos(x, y, spd); 3097 }; 3098 3099 this.doScrollTop = function(y, spd) { //no-trans 3100 var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft(); 3101 self.doScrollPos(x, y, spd); 3102 }; 3103 3104 this.doScrollPos = function(x, y, spd) { //no-trans 3105 var y = (y === undefined || y === false) ? self.getScrollTop(true) : y; 3106 3107 if ((self.timer) && (self.newscrolly == y) && (self.newscrollx == x)) return true; 3108 3109 if (self.timer) clearAnimationFrame(self.timer); 3110 self.timer = 0; 3111 3112 var py = self.getScrollTop(); 3113 var px = self.getScrollLeft(); 3114 3115 if (((self.newscrolly - py) * (y - py) < 0) || ((self.newscrollx - px) * (x - px) < 0)) self.cancelScroll(); //inverted movement detection 3116 3117 self.newscrolly = y; 3118 self.newscrollx = x; 3119 3120 if (!self.bouncescroll || !self.rail.visibility) { 3121 if (self.newscrolly < 0) { 3122 self.newscrolly = 0; 3123 } else if (self.newscrolly > self.page.maxh) { 3124 self.newscrolly = self.page.maxh;
3125 } 3126 } 3127 if (!self.bouncescroll || !self.railh.visibility) { 3128 if (self.newscrollx < 0) { 3129 self.newscrollx = 0; 3130 } else if (self.newscrollx > self.page.maxw) { 3131 self.newscrollx = self.page.maxw; 3132 } 3133 } 3134 3135 self.dst = {}; 3136 self.dst.x = x - px; 3137 self.dst.y = y - py; 3138 self.dst.px = px; 3139 self.dst.py = py; 3140 3141 var dst = Math.round(Math.sqrt(Math.pow(self.dst.x, 2) + Math.pow(self.dst.y, 2))); 3142 3143 self.dst.ax = self.dst.x / dst; 3144 self.dst.ay = self.dst.y / dst; 3145 3146 var pa = 0; 3147 var pe = dst; 3148 3149 if (self.dst.x == 0) { 3150 pa = py; 3151 pe = y; 3152 self.dst.ay = 1; 3153 self.dst.py = 0; 3154 } else if (self.dst.y == 0) { 3155 pa = px; 3156 pe = x; 3157 self.dst.ax = 1; 3158 self.dst.px = 0; 3159 } 3160 3161 var ms = self.getTransitionSpeed(dst); 3162 if (spd && spd <= 1) ms *= spd; 3163 if (ms > 0) { 3164 self.bzscroll = (self.bzscroll) ? self.bzscroll.update(pe, ms) : new BezierClass(pa, pe, ms, 0, 1, 0, 1); 3165 } else { 3166 self.bzscroll = false; 3167 } 3168 3169 if (self.timer) return; 3170 3171 if ((py == self.page.maxh && y >= self.page.maxh) || (px == self.page.maxw && x >= self.page.maxw)) self.checkContentSize(); 3172 3173 var sync = 1; 3174 3175 function scrolling() { 3176 if (self.cancelAnimationFrame) return true; 3177 3178 self.scrollrunning = true; 3179 3180 sync = 1 - sync; 3181 if (sync) return (self.timer = setAnimationFrame(scrolling) || 1); 3182 3183 var done = 0; 3184 var sx, sy; 3185 3186 var sc = sy = self.getScrollTop(); 3187 if (self.dst.ay) { 3188 sc = (self.bzscroll) ? self.dst.py + (self.bzscroll.getNow() * self.dst.ay) : self.newscrolly; 3189 var dr = sc - sy; 3190 if ((dr < 0 && sc < self.newscrolly) || (dr > 0 && sc > self.newscrolly)) sc = self.newscrolly; 3191 self.setScrollTop(sc); 3192 if (sc == self.newscrolly) done = 1; 3193 } else { 3194 done = 1; 3195 } 3196 3197 var scx = sx = self.getScrollLeft(); 3198 if (self.dst.ax) { 3199 scx = (self.bzscroll) ? self.dst.px + (self.bzscroll.getNow() * self.dst.ax) : self.newscrollx; 3200 var dr = scx - sx; 3201 if ((dr < 0 && scx < self.newscrollx) || (dr > 0 && scx > self.newscrollx)) scx = self.newscrollx; 3202 self.setScrollLeft(scx); 3203 if (scx == self.newscrollx) done += 1; 3204 } else { 3205 done += 1; 3206 } 3207 3208 if (done == 2) { 3209 self.timer = 0; 3210 self.cursorfreezed = false; 3211 self.bzscroll = false; 3212 self.scrollrunning = false; 3213 if (sc < 0) sc = 0; 3214 else if (sc > self.page.maxh) sc = Math.max(0,self.page.maxh); 3215 if (scx < 0) scx = 0; 3216 else if (scx > self.page.maxw) scx = self.page.maxw; 3217 if ((scx != self.newscrollx) || (sc != self.newscrolly)) self.doScrollPos(scx, sc); 3218 else { 3219 if (self.onscrollend) { 3220 self.triggerScrollEnd(); 3221 } 3222 } 3223 } else { 3224 self.timer = setAnimationFrame(scrolling) || 1; 3225 } 3226 } 3227 self.cancelAnimationFrame = false; 3228 self.timer = 1; 3229 3230 if (self.onscrollstart && !self.scrollrunning) { 3231 var info = { 3232 "type": "scrollstart", 3233 "current": { 3234 "x": px, 3235 "y": py 3236 }, 3237 "request": { 3238 "x": x, 3239 "y": y 3240 }, 3241 "end": { 3242 "x": self.newscrollx, 3243 "y": self.newscrolly 3244 }, 3245 "speed": ms 3246 }; 3247 self.onscrollstart.call(self, info); 3248 } 3249 3250 scrolling(); 3251 3252 if ((py == self.page.maxh && y >= py) || (px == self.page.maxw && x >= px)) self.checkContentSize(); 3253 3254 self.noticeCursor(); 3255 }; 3256 3257 this.cancelScroll = function() { 3258 if (self.timer) clearAnimationFrame(self.timer); 3259 self.timer = 0; 3260 self.bzscroll = false; 3261 self.scrollrunning = false; 3262 return self; 3263 }; 3264 3265 } 3266 3267 this.doScrollBy = function(stp, relative) { 3268 var ny = 0; 3269 if (relative) { 3270 ny = Math.floor((self.scroll.y - stp) * self.scrollratio.y); 3271 } else { 3272 var sy = (self.timer) ? self.newscrolly : self.getScrollTop(true); 3273 ny = sy - stp; 3274 } 3275 if (self.bouncescroll) { 3276 var haf = Math.round(self.view.h / 2); 3277 if (ny < -haf) ny = -haf; 3278 else if (ny > (self.page.maxh + haf)) ny = (self.page.maxh + haf); 3279 } 3280 self.cursorfreezed = false; 3281 3282 var py = self.getScrollTop(true); 3283 if (ny < 0 && py <= 0) return self.noticeCursor(); 3284 else if (ny > self.page.maxh && py >= self.page.maxh) { 3285 self.checkContentSize(); 3286 return self.noticeCursor(); 3287 } 3288 3289 self.doScrollTop(ny); 3290 }; 3291 3292 this.doScrollLeftBy = function(stp, relative) { 3293 var nx = 0; 3294 if (relative) { 3295 nx = Math.floor((self.scroll.x - stp) * self.scrollratio.x); 3296 } else { 3297 var sx = (self.timer) ? self.newscrollx : self.getScrollLeft(true); 3298 nx = sx - stp; 3299 } 3300 if (self.bouncescroll) { 3301 var haf = Math.round(self.view.w / 2); 3302 if (nx < -haf) nx = -haf; 3303 else if (nx > (self.page.maxw + haf)) nx = (self.page.maxw + haf); 3304 } 3305 self.cursorfreezed = false; 3306 3307 var px = self.getScrollLeft(true); 3308 if (nx < 0 && px <= 0) return self.noticeCursor(); 3309 else if (nx > self.page.maxw && px >= self.page.maxw) return self.noticeCursor(); 3310 3311 self.doScrollLeft(nx); 3312 }; 3313 3314 this.doScrollTo = function(pos, relative) { 3315 var ny = (relative) ? Math.round(pos * self.scrollratio.y) : pos; 3316 if (ny < 0) ny = 0; 3317 else if (ny > self.page.maxh) ny = self.page.maxh;
vendor: 13,081 bytes, lines 3318-3779
3318 self.cursorfreezed = false; 3319 self.doScrollTop(pos); 3320 }; 3321 3322 this.checkContentSize = function() { 3323 var pg = self.getContentSize(); 3324 if ((pg.h != self.page.h) || (pg.w != self.page.w)) self.resize(false, pg); 3325 }; 3326 3327 self.onscroll = function(e) { 3328 if (self.rail.drag) return; 3329 if (!self.cursorfreezed) { 3330 self.synched('scroll', function() { 3331 self.scroll.y = Math.round(self.getScrollTop() * (1 / self.scrollratio.y)); 3332 if (self.railh) self.scroll.x = Math.round(self.getScrollLeft() * (1 / self.scrollratio.x)); 3333 self.noticeCursor(); 3334 }); 3335 } 3336 }; 3337 self.bind(self.docscroll, "scroll", self.onscroll); 3338 3339 this.doZoomIn = function(e) { 3340 if (self.zoomactive) return; 3341 self.zoomactive = true; 3342 3343 self.zoomrestore = { 3344 style: {} 3345 }; 3346 var lst = ['position', 'top', 'left', 'zIndex', 'backgroundColor', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight']; 3347 var win = self.win[0].style; 3348 for (var a in lst) { 3349 var pp = lst[a]; 3350 self.zoomrestore.style[pp] = (win[pp] !== undefined) ? win[pp] : ''; 3351 } 3352 3353 self.zoomrestore.style.width = self.win.css('width'); 3354 self.zoomrestore.style.height = self.win.css('height'); 3355 3356 self.zoomrestore.padding = { 3357 w: self.win.outerWidth() - self.win.width(), 3358 h: self.win.outerHeight() - self.win.height() 3359 }; 3360 3361 if (cap.isios4) { 3362 self.zoomrestore.scrollTop = $(window).scrollTop(); 3363 $(window).scrollTop(0); 3364 } 3365 3366 self.win.css({ 3367 position: (cap.isios4) ? "absolute" : "fixed", 3368 top: 0, 3369 left: 0, 3370 zIndex: globalmaxzindex + 100, 3371 margin: 0 3372 }); 3373 var bkg = self.win.css("backgroundColor"); 3374 if (bkg == "" || /transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(bkg)) self.win.css("backgroundColor", "#fff"); 3375 self.rail.css({ 3376 zIndex: globalmaxzindex + 101 3377 }); 3378 self.zoom.css({ 3379 zIndex: globalmaxzindex + 102 3380 }); 3381 self.zoom.css('backgroundPosition', '0px -18px'); 3382 self.resizeZoom(); 3383 3384 if (self.onzoomin) self.onzoomin.call(self); 3385 3386 return self.cancelEvent(e); 3387 }; 3388 3389 this.doZoomOut = function(e) { 3390 if (!self.zoomactive) return; 3391 self.zoomactive = false; 3392 3393 self.win.css("margin", ""); 3394 self.win.css(self.zoomrestore.style); 3395 3396 if (cap.isios4) { 3397 $(window).scrollTop(self.zoomrestore.scrollTop); 3398 } 3399 3400 self.rail.css({ 3401 "z-index": self.zindex 3402 }); 3403 self.zoom.css({ 3404 "z-index": self.zindex 3405 }); 3406 self.zoomrestore = false; 3407 self.zoom.css('backgroundPosition', '0px 0px'); 3408 self.onResize(); 3409 3410 if (self.onzoomout) self.onzoomout.call(self); 3411 3412 return self.cancelEvent(e); 3413 }; 3414 3415 this.doZoom = function(e) { 3416 return (self.zoomactive) ? self.doZoomOut(e) : self.doZoomIn(e); 3417 }; 3418 3419 this.resizeZoom = function() { 3420 if (!self.zoomactive) return; 3421 3422 var py = self.getScrollTop(); //preserve scrolling position 3423 self.win.css({ 3424 width: $(window).width() - self.zoomrestore.padding.w + "px", 3425 height: $(window).height() - self.zoomrestore.padding.h + "px" 3426 }); 3427 self.onResize(); 3428 3429 self.setScrollTop(Math.min(self.page.maxh, py)); 3430 }; 3431 3432 this.init(); 3433 3434 $.nicescroll.push(this); 3435 3436 }; 3437 3438 // Inspired by the work of Kin Blas 3439 // http://webpro.host.adobe.com/people/jblas/momentum/includes/jquery.momentum.0.7.js 3440 3441 3442 var ScrollMomentumClass2D = function(nc) { 3443 var self = this; 3444 this.nc = nc; 3445 3446 this.lastx = 0; 3447 this.lasty = 0; 3448 this.speedx = 0; 3449 this.speedy = 0; 3450 this.lasttime = 0; 3451 this.steptime = 0; 3452 this.snapx = false; 3453 this.snapy = false; 3454 this.demulx = 0; 3455 this.demuly = 0; 3456 3457 this.lastscrollx = -1; 3458 this.lastscrolly = -1; 3459 3460 this.chkx = 0; 3461 this.chky = 0; 3462 3463 this.timer = 0; 3464 3465 this.time = function() { 3466 return +new Date(); //beautifull hack 3467 }; 3468 3469 this.reset = function(px, py) { 3470 self.stop(); 3471 var now = self.time(); 3472 self.steptime = 0; 3473 self.lasttime = now; 3474 self.speedx = 0; 3475 self.speedy = 0; 3476 self.lastx = px; 3477 self.lasty = py; 3478 self.lastscrollx = -1; 3479 self.lastscrolly = -1; 3480 }; 3481 3482 this.update = function(px, py) { 3483 var now = self.time(); 3484 self.steptime = now - self.lasttime; 3485 self.lasttime = now; 3486 var dy = py - self.lasty; 3487 var dx = px - self.lastx; 3488 var sy = self.nc.getScrollTop(); 3489 var sx = self.nc.getScrollLeft(); 3490 var newy = sy + dy; 3491 var newx = sx + dx; 3492 self.snapx = (newx < 0) || (newx > self.nc.page.maxw); 3493 self.snapy = (newy < 0) || (newy > self.nc.page.maxh); 3494 self.speedx = dx; 3495 self.speedy = dy; 3496 self.lastx = px; 3497 self.lasty = py; 3498 }; 3499 3500 this.stop = function() { 3501 self.nc.unsynched("domomentum2d"); 3502 if (self.timer) clearTimeout(self.timer); 3503 self.timer = 0; 3504 self.lastscrollx = -1; 3505 self.lastscrolly = -1; 3506 }; 3507 3508 this.doSnapy = function(nx, ny) { 3509 var snap = false; 3510 3511 if (ny < 0) { 3512 ny = 0; 3513 snap = true; 3514 } else if (ny > self.nc.page.maxh) { 3515 ny = self.nc.page.maxh; 3516 snap = true; 3517 } 3518 3519 if (nx < 0) { 3520 nx = 0; 3521 snap = true; 3522 } else if (nx > self.nc.page.maxw) { 3523 nx = self.nc.page.maxw; 3524 snap = true; 3525 } 3526 3527 (snap) ? self.nc.doScrollPos(nx, ny, self.nc.opt.snapbackspeed): self.nc.triggerScrollEnd(); 3528 }; 3529 3530 this.doMomentum = function(gp) { 3531 var t = self.time(); 3532 var l = (gp) ? t + gp : self.lasttime; 3533 3534 var sl = self.nc.getScrollLeft(); 3535 var st = self.nc.getScrollTop(); 3536 3537 var pageh = self.nc.page.maxh; 3538 var pagew = self.nc.page.maxw; 3539 3540 self.speedx = (pagew > 0) ? Math.min(60, self.speedx) : 0; 3541 self.speedy = (pageh > 0) ? Math.min(60, self.speedy) : 0; 3542 3543 var chk = l && (t - l) <= 60; 3544 3545 if ((st < 0) || (st > pageh) || (sl < 0) || (sl > pagew)) chk = false; 3546 3547 var sy = (self.speedy && chk) ? self.speedy : false; 3548 var sx = (self.speedx && chk) ? self.speedx : false; 3549 3550 if (sy || sx) { 3551 var tm = Math.max(16, self.steptime); //timeout granularity 3552 3553 if (tm > 50) { // do smooth 3554 var xm = tm / 50; 3555 self.speedx *= xm; 3556 self.speedy *= xm; 3557 tm = 50; 3558 } 3559 3560 self.demulxy = 0; 3561 3562 self.lastscrollx = self.nc.getScrollLeft(); 3563 self.chkx = self.lastscrollx; 3564 self.lastscrolly = self.nc.getScrollTop(); 3565 self.chky = self.lastscrolly; 3566 3567 var nx = self.lastscrollx; 3568 var ny = self.lastscrolly; 3569 3570 var onscroll = function() { 3571 var df = ((self.time() - t) > 600) ? 0.04 : 0.02; 3572 3573 if (self.speedx) { 3574 nx = Math.floor(self.lastscrollx - (self.speedx * (1 - self.demulxy))); 3575 self.lastscrollx = nx; 3576 if ((nx < 0) || (nx > pagew)) df = 0.10; 3577 } 3578 3579 if (self.speedy) { 3580 ny = Math.floor(self.lastscrolly - (self.speedy * (1 - self.demulxy))); 3581 self.lastscrolly = ny; 3582 if ((ny < 0) || (ny > pageh)) df = 0.10; 3583 } 3584 3585 self.demulxy = Math.min(1, self.demulxy + df); 3586 3587 self.nc.synched("domomentum2d", function() { 3588 3589 if (self.speedx) { 3590 var scx = self.nc.getScrollLeft(); 3591// if (scx != self.chkx) self.stop(); 3592 self.chkx = nx; 3593 self.nc.setScrollLeft(nx); 3594 } 3595 3596 if (self.speedy) { 3597 var scy = self.nc.getScrollTop(); 3598// if (scy != self.chky) self.stop(); 3599 self.chky = ny; 3600 self.nc.setScrollTop(ny); 3601 } 3602 3603 if (!self.timer) { 3604 self.nc.hideCursor(); 3605 self.doSnapy(nx, ny); 3606 } 3607 3608 }); 3609 3610 if (self.demulxy < 1) { 3611 self.timer = setTimeout(onscroll, tm); 3612 } else { 3613 self.stop(); 3614 self.nc.hideCursor(); 3615 self.doSnapy(nx, ny); 3616 } 3617 }; 3618 3619 onscroll(); 3620 3621 } else { 3622 self.doSnapy(self.nc.getScrollLeft(), self.nc.getScrollTop()); 3623 } 3624 3625 }; 3626 3627 }; 3628 3629 3630 // override jQuery scrollTop 3631 3632 var _scrollTop = jQuery.fn.scrollTop; // preserve original function 3633 3634 jQuery.cssHooks.pageYOffset = { 3635 get: function(elem, computed, extra) { 3636 var nice = $.data(elem, '__nicescroll') || false; 3637 return (nice && nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(elem); 3638 }, 3639 set: function(elem, value) { 3640 var nice = $.data(elem, '__nicescroll') || false; 3641 (nice && nice.ishwscroll) ? nice.setScrollTop(parseInt(value)): _scrollTop.call(elem, value); 3642 return this; 3643 } 3644 }; 3645 3646 /* 3647 $.fx.step["scrollTop"] = function(fx){ 3648 $.cssHooks["scrollTop"].set( fx.elem, fx.now + fx.unit ); 3649 }; 3650*/ 3651 3652 jQuery.fn.scrollTop = function(value) { 3653 if (value === undefined) { 3654 var nice = (this[0]) ? $.data(this[0], '__nicescroll') || false : false; 3655 return (nice && nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(this); 3656 } else { 3657 return this.each(function() { 3658 var nice = $.data(this, '__nicescroll') || false; 3659 (nice && nice.ishwscroll) ? nice.setScrollTop(parseInt(value)): _scrollTop.call($(this), value); 3660 }); 3661 } 3662 }; 3663 3664 // override jQuery scrollLeft 3665 3666 var _scrollLeft = jQuery.fn.scrollLeft; // preserve original function 3667 3668 $.cssHooks.pageXOffset = { 3669 get: function(elem, computed, extra) { 3670 var nice = $.data(elem, '__nicescroll') || false; 3671 return (nice && nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(elem); 3672 }, 3673 set: function(elem, value) { 3674 var nice = $.data(elem, '__nicescroll') || false; 3675 (nice && nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)): _scrollLeft.call(elem, value); 3676 return this; 3677 } 3678 }; 3679 3680 /* 3681 $.fx.step["scrollLeft"] = function(fx){ 3682 $.cssHooks["scrollLeft"].set( fx.elem, fx.now + fx.unit ); 3683 }; 3684*/ 3685 3686 jQuery.fn.scrollLeft = function(value) { 3687 if (value === undefined) { 3688 var nice = (this[0]) ? $.data(this[0], '__nicescroll') || false : false; 3689 return (nice && nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(this); 3690 } else { 3691 return this.each(function() { 3692 var nice = $.data(this, '__nicescroll') || false; 3693 (nice && nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)): _scrollLeft.call($(this), value); 3694 }); 3695 } 3696 }; 3697 3698 var NiceScrollArray = function(doms) { 3699 var self = this; 3700 this.length = 0; 3701 this.name = "nicescrollarray"; 3702 3703 this.each = function(fn) { 3704 $.each(self, fn); 3705 return self; 3706 }; 3707 3708 this.push = function(nice) { 3709 self[self.length] = nice; 3710 self.length++; 3711 }; 3712 3713 this.eq = function(idx) { 3714 return self[idx]; 3715 }; 3716 3717 if (doms) { 3718 for (var a = 0; a < doms.length; a++) { 3719 var nice = $.data(doms[a], '__nicescroll') || false; 3720 if (nice) { 3721 this[this.length] = nice; 3722 this.length++; 3723 } 3724 } 3725 } 3726 3727 return this; 3728 }; 3729 3730 function mplex(el, lst, fn) { 3731 for (var a = 0; a < lst.length; a++) fn(el, lst[a]); 3732 } 3733 mplex( 3734 NiceScrollArray.prototype, ['show', 'hide', 'toggle', 'onResize', 'resize', 'remove', 'stop', 'doScrollPos'], 3735 function(e, n) { 3736 e[n] = function() { 3737 var args = arguments; 3738 return this.each(function() { 3739 this[n].apply(this, args); 3740 }); 3741 }; 3742 } 3743 ); 3744 3745 jQuery.fn.getNiceScroll = function(index) { 3746 if (index === undefined) { 3747 return new NiceScrollArray(this); 3748 } else { 3749 return this[index] && $.data(this[index], '__nicescroll') || false; 3750 } 3751 }; 3752 3753 jQuery.expr[':'].nicescroll = function(a) { 3754 return $.data(a, '__nicescroll') !== undefined; 3755 }; 3756 3757 $.fn.niceScroll = function(wrapper, opt) { 3758 if (opt === undefined && typeof wrapper == "object" && !("jquery" in wrapper)) { 3759 opt = wrapper; 3760 wrapper = false; 3761 } 3762 opt = $.extend({},opt); // cloning 3763 var ret = new NiceScrollArray(); 3764 if (opt === undefined) opt = {}; 3765 3766 if (wrapper || false) { 3767 opt.doc = $(wrapper); 3768 opt.win = $(this); 3769 } 3770 var docundef = !("doc" in opt); 3771 if (!docundef && !("win" in opt)) opt.win = $(this); 3772 3773 this.each(function() { 3774 var nice = $(this).data('__nicescroll') || false; 3775 if (!nice) { 3776 opt.doc = (docundef) ? $(this) : opt.doc; 3777 nice = new NiceScrollClass(opt, $(this)); 3778 $(this).data('__nicescroll', nice); 3779 }
3780 ret.push(nice); 3781 }); 3782 return (ret.length == 1) ? ret[0] : ret; 3783 }; 3784 3785 window.NiceScroll = { 3786 getjQuery: function() { 3787 return jQuery; 3788 } 3789 }; 3790 3791 if (!$.nicescroll) { 3792 $.nicescroll = new NiceScrollArray(); 3793 $.nicescroll.options = _globaloptions; 3794 } 3795 3796})); 3797
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.