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