1/* 2 * JavaScript Custom Forms 1.4.1 3 */ 4jcf = { 5 // global options 6 modules: {}, 7 plugins: {}, 8 baseOptions: { 9 useNativeDropOnMobileDevices: false, 10 unselectableClass:'jcf-unselectable', 11 labelActiveClass:'jcf-label-active', 12 labelDisabledClass:'jcf-label-disabled', 13 classPrefix: 'jcf-class-', 14 hiddenClass:'jcf-hidden', 15 focusClass:'jcf-focus', 16 wrapperTag: 'div' 17 }, 18 // replacer function 19 customForms: { 20 setOptions: function(obj) { 21 for(var p in obj) { 22 if(obj.hasOwnProperty(p) && typeof obj[p] === 'object') { 23 jcf.lib.extend(jcf.modules[p].prototype.defaultOptions, obj[p]); 24 } 25 } 26 }, 27 replaceAll: function() { 28 for(var k in jcf.modules) { 29 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector); 30 for(var i = 0; i<els.length; i++) { 31 if(els[i].jcf) { 32 // refresh form element state 33 els[i].jcf.refreshState(); 34 } else { 35 // replace form element 36 if(!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) { 37 new jcf.modules[k]({ 38 replaces:els[i] 39 }); 40 } 41 } 42 } 43 } 44 }, 45 refreshAll: function() { 46 for(var k in jcf.modules) { 47 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector); 48 for(var i = 0; i<els.length; i++) { 49 if(els[i].jcf) { 50 // refresh form element state 51 els[i].jcf.refreshState(); 52 } 53 } 54 } 55 }, 56 refreshElement: function(obj) { 57 if(obj && obj.jcf) { 58 obj.jcf.refreshState(); 59 } 60 }, 61 destroyAll: function() { 62 for(var k in jcf.modules) { 63 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector); 64 for(var i = 0; i<els.length; i++) { 65 if(els[i].jcf) { 66 els[i].jcf.destroy(); 67 } 68 } 69 } 70 } 71 }, 72 // detect device type 73 isTouchDevice: (function() { 74 try { 75 return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; 76 } catch (e) { 77 return false; 78 } 79 }()), 80 // define base module 81 setBaseModule: function(obj) { 82 jcf.customControl = function(opt){ 83 this.options = jcf.lib.extend({}, jcf.baseOptions, this.defaultOptions, opt); 84 this.init(); 85 } 86 for(var p in obj) { 87 jcf.customControl.prototype[p] = obj[p]; 88 } 89 }, 90 // add module to jcf.modules 91 addModule: function(obj) { 92 if(obj.name){ 93 // create new module proto class 94 jcf.modules[obj.name] = function(){ 95 jcf.modules[obj.name].superclass.constructor.apply(this, arguments); 96 } 97 jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl); 98 for(var p in obj) { 99 jcf.modules[obj.name].prototype[p] = obj[p] 100 } 101 // on create module 102 jcf.modules[obj.name].prototype.onCreateModule(); 103 // make callback for exciting modules 104 for(var mod in jcf.modules) { 105 if(jcf.modules[mod] != jcf.modules[obj.name]) { 106 jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]); 107 } 108 } 109 } 110 }, 111 // add plugin to jcf.plugins 112 addPlugin: function(obj) { 113 if(obj && obj.name) { 114 jcf.plugins[obj.name] = function() { 115 this.init.apply(this, arguments); 116 } 117 for(var p in obj) { 118 jcf.plugins[obj.name].prototype[p] = obj[p]; 119 } 120 } 121 }, 122 // miscellaneous init 123 init: function(){ 124 this.eventPress = this.isTouchDevice ? 'touchstart' : 'mousedown'; 125 this.eventMove = this.isTouchDevice ? 'touchmove' : 'mousemove'; 126 this.eventRelease = this.isTouchDevice ? 'touchend' : 'mouseup'; 127 return this; 128 }, 129 initStyles: function() { 130 // create <style> element and rules 131 var head = document.getElementsByTagName('head')[0], 132 style = document.createElement('style'), 133 rules = document.createTextNode('.'+jcf.baseOptions.unselectableClass+'{'+ 134 '-moz-user-select:none;'+ 135 '-webkit-tap-highlight-color:rgba(255,255,255,0);'+ 136 '-webkit-user-select:none;'+ 137 'user-select:none;'+ 138 '}'); 139 140 // append style element 141 style.type = 'text/css'; 142 if(style.styleSheet) { 143 style.styleSheet.cssText = rules.nodeValue; 144 } else { 145 style.appendChild(rules); 146 } 147 head.appendChild(style); 148 } 149}.init(); 150 151/* 152 * Custom Form Control prototype 153 */ 154jcf.setBaseModule({ 155 init: function(){ 156 if(this.options.replaces) { 157 this.realElement = this.options.replaces; 158 this.realElement.jcf = this; 159 this.replaceObject(); 160 } 161 }, 162 defaultOptions: { 163 // default module options (will be merged with base options) 164 }, 165 checkElement: function(el){ 166 return true;
166 // additional check for correct form element 167 }, 168 replaceObject: function(){ 169 this.createWrapper(); 170 this.attachEvents(); 171 this.fixStyles(); 172 this.setupWrapper(); 173 }, 174 createWrapper: function(){ 175 this.fakeElement = jcf.lib.createElement(this.options.wrapperTag); 176 this.labelFor = jcf.lib.getLabelFor(this.realElement); 177 jcf.lib.disableTextSelection(this.fakeElement); 178 jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.classPrefix)); 179 jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass); 180 }, 181 attachEvents: function(){ 182 jcf.lib.event.add(this.realElement, 'focus', this.onFocusHandler, this); 183 jcf.lib.event.add(this.realElement, 'blur', this.onBlurHandler, this); 184 jcf.lib.event.add(this.fakeElement, 'click', this.onFakeClick, this); 185 jcf.lib.event.add(this.fakeElement, jcf.eventPress, this.onFakePressed, this); 186 jcf.lib.event.add(this.fakeElement, jcf.eventRelease, this.onFakeReleased, this); 187 188 if(this.labelFor) { 189 this.labelFor.jcf = this; 190 jcf.lib.event.add(this.labelFor, 'click', this.onFakeClick, this); 191 jcf.lib.event.add(this.labelFor, jcf.eventPress, this.onFakePressed, this); 192 jcf.lib.event.add(this.labelFor, jcf.eventRelease, this.onFakeReleased, this); 193 } 194 }, 195 fixStyles: function() { 196 // hide mobile webkit tap effect 197 if(jcf.isTouchDevice) { 198 var tapStyle = 'rgba(255,255,255,0)'; 199 this.realElement.style.webkitTapHighlightColor = tapStyle; 200 this.fakeElement.style.webkitTapHighlightColor = tapStyle; 201 if(this.labelFor) { 202 this.labelFor.style.webkitTapHighlightColor = tapStyle; 203 } 204 } 205 }, 206 setupWrapper: function(){ 207 // implement in subclass 208 }, 209 refreshState: function(){ 210 // implement in subclass 211 }, 212 destroy: function() { 213 if(this.fakeElement && this.fakeElement.parentNode) { 214 this.fakeElement.parentNode.removeChild(this.fakeElement); 215 } 216 jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass); 217 this.realElement.jcf = null; 218 }, 219 onFocus: function(){ 220 // emulated focus event 221 jcf.lib.addClass(this.fakeElement,this.options.focusClass); 222 }, 223 onBlur: function(cb){ 224 // emulated blur event 225 jcf.lib.removeClass(this.fakeElement,this.options.focusClass); 226 }, 227 onFocusHandler: function() { 228 // handle focus loses 229 if(this.focused) return; 230 this.focused = true; 231 232 // handle touch devices also 233 if(jcf.isTouchDevice) { 234 if(jcf.focusedInstance && jcf.focusedInstance.realElement != this.realElement) { 235 jcf.focusedInstance.onBlur(); 236 jcf.focusedInstance.realElement.blur(); 237 } 238 jcf.focusedInstance = this; 239 } 240 this.onFocus.apply(this, arguments); 241 }, 242 onBlurHandler: function() { 243 // handle focus loses 244 if(!this.pressedFlag) { 245 this.focused = false; 246 this.onBlur.apply(this, arguments); 247 } 248 }, 249 onFakeClick: function(){ 250 if(jcf.isTouchDevice) { 251 this.onFocus(); 252 } else if(!this.realElement.disabled) { 253 this.realElement.focus(); 254 } 255 }, 256 onFakePressed: function(e){ 257 this.pressedFlag = true; 258 }, 259 onFakeReleased: function(){ 260 this.pressedFlag = false; 261 }, 262 onCreateModule: function(){ 263 // implement in subclass 264 }, 265 onModuleAdded: function(module) { 266 // implement in subclass 267 }, 268 onControlReady: function() { 269 // implement in subclass 270 } 271}); 272 273/* 274 * JCF Utility Library 275 */ 276jcf.lib = { 277 bind: function(func, scope){ 278 return function() { 279 return func.apply(scope, arguments); 280 } 281 }, 282 browser: (function() { 283 var ua = navigator.userAgent.toLowerCase(), res = {}, 284 match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) || 285 /(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || []; 286 res[match[1]] = true; 287 res.version = match[2] || "0"; 288 res.safariMac = ua.indexOf('mac') != -1 && ua.indexOf('safari') != -1; 289 return res; 290 })(), 291 getOffset: function (obj) { 292 if (obj.getBoundingClientRect) { 293 var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft; 294 var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; 295 var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0; 296 var clientTop = document.documentElement.clientTop || document.body.clientTop || 0; 297 return { 298 top:Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop), 299 left:Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft) 300 } 301 } else { 302 var posLeft = 0, posTop = 0; 303 while (obj.offsetParent) {posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent;}
304 return {top:posTop,left:posLeft}; 305 } 306 }, 307 getScrollTop: function() { 308 return window.pageYOffset || document.documentElement.scrollTop; 309 }, 310 getScrollLeft: function() { 311 return window.pageXOffset || document.documentElement.scrollLeft; 312 }, 313 getWindowWidth: function(){ 314 return document.compatMode=='CSS1Compat' ? document.documentElement.clientWidth : document.body.clientWidth; 315 }, 316 getWindowHeight: function(){ 317 return document.compatMode=='CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight; 318 }, 319 getStyle: function(el, prop) { 320 if (document.defaultView && document.defaultView.getComputedStyle) { 321 return document.defaultView.getComputedStyle(el, null)[prop]; 322 } else if (el.currentStyle) { 323 return el.currentStyle[prop]; 324 } else { 325 return el.style[prop]; 326 } 327 }, 328 getParent: function(obj, selector) { 329 while(obj.parentNode && obj.parentNode != document.body) { 330 if(obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) { 331 return obj.parentNode; 332 } 333 obj = obj.parentNode; 334 } 335 return false; 336 }, 337 isParent: function(child, parent) { 338 while(child.parentNode) { 339 if(child.parentNode === parent) { 340 return true; 341 } 342 child = child.parentNode; 343 } 344 return false; 345 }, 346 getLabelFor: function(object) { 347 if(jcf.lib.getParent(object,'label')) { 348 return object.parentNode; 349 } else if(object.id) { 350 return jcf.lib.queryBySelector('label[for="' + object.id + '"]')[0]; 351 } 352 }, 353 disableTextSelection: function(el){ 354 if (typeof el.onselectstart !== 'undefined') { 355 el.onselectstart = function() {return false}; 356 } else if(window.opera) { 357 el.setAttribute('unselectable', 'on'); 358 } else { 359 jcf.lib.addClass(el, jcf.baseOptions.unselectableClass); 360 } 361 }, 362 enableTextSelection: function(el) { 363 if (typeof el.onselectstart !== 'undefined') { 364 el.onselectstart = null; 365 } else if(window.opera) { 366 el.removeAttribute('unselectable'); 367 } else { 368 jcf.lib.removeClass(el, jcf.baseOptions.unselectableClass); 369 } 370 }, 371 queryBySelector: function(selector, scope){ 372 return this.getElementsBySelector(selector, scope); 373 }, 374 prevSibling: function(node) { 375 while(node = node.previousSibling) if(node.nodeType == 1) break; 376 return node; 377 }, 378 nextSibling: function(node) { 379 while(node = node.nextSibling) if(node.nodeType == 1) break; 380 return node; 381 }, 382 fireEvent: function(element,event) { 383 if (document.createEventObject){ 384 var evt = document.createEventObject(); 385 return element.fireEvent('on'+event,evt) 386 } 387 else{ 388 var evt = document.createEvent('HTMLEvents'); 389 evt.initEvent(event, true, true ); 390 return !element.dispatchEvent(evt); 391 } 392 }, 393 isParent: function(p, c) { 394 while(c.parentNode) { 395 if(p == c) { 396 return true; 397 } 398 c = c.parentNode; 399 } 400 return false; 401 }, 402 inherit: function(Child, Parent) { 403 var F = function() { } 404 F.prototype = Parent.prototype 405 Child.prototype = new F() 406 Child.prototype.constructor = Child 407 Child.superclass = Parent.prototype 408 }, 409 extend: function(obj) { 410 for(var i = 1; i < arguments.length; i++) { 411 for(var p in arguments[i]) { 412 if(arguments[i].hasOwnProperty(p)) { 413 obj[p] = arguments[i][p]; 414 } 415 } 416 } 417 return obj; 418 }, 419 hasClass: function (obj,cname) { 420 return (obj.className ? obj.className.match(new RegExp('(\\s|^)'+cname+'(\\s|$)')) : false); 421 }, 422 addClass: function (obj,cname) { 423 if (!this.hasClass(obj,cname)) obj.className += (!obj.className.length || obj.className.charAt(obj.className.length - 1) === ' ' ? '' : ' ') + cname; 424 }, 425 removeClass: function (obj,cname) { 426 if (this.hasClass(obj,cname)) obj.className=obj.className.replace(new RegExp('(\\s|^)'+cname+'(\\s|$)'),' ').replace(/\s+$/, ''); 427 }, 428 toggleClass: function(obj, cname, condition) { 429 if(condition) this.addClass(obj, cname); else this.removeClass(obj, cname); 430 }, 431 createElement: function(tagName, options) { 432 var el = document.createElement(tagName); 433 for(var p in options) { 434 if(options.hasOwnProperty(p)) { 435 switch (p) { 436 case 'class': el.className = options[p]; break; 437 case 'html': el.innerHTML = options[p]; break; 438 case 'style': this.setStyles(el, options[p]); break; 439 default: el.setAttribute(p, options[p]); 440 } 441 } 442 } 443 return el; 444 }, 445 setStyles: function(el, styles) { 446 for(var p in styles) { 447 if(styles.hasOwnProperty(p)) { 448 switch (p) { 449 case 'float': el.style.cssFloat = styles[p]; break; 450 case 'opacity': el.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+styles[p]*100+')'; el.style.opacity = styles[p]; break; 451 default: el.style[p] = (typeof styles[p] === 'undefined' ? 0 : styles[p]) + (typeof styles[p] === 'number' ? 'px' : ''); 452 } 453 } 454 } 455 return el; 456 }, 457 getInnerWidth: function(el) { 458 return el.offsetWidth - (parseInt(this.getStyle(el,'paddingLeft')) || 0) - (parseInt(this.getStyle(el,'paddingRight')) || 0); 459 }, 460 getInnerHeight: function(el) { 461 return el.offsetHeight - (parseInt(this.getStyle(el,'paddingTop')) || 0) - (parseInt(this.getStyle(el,'paddingBottom')) || 0); 462 }, 463 getAllClasses: function(cname, prefix, skip) { 464 if(!skip) skip = ''; 465 if(!prefix) prefix = ''; 466 return cname ? cname.replace(new RegExp('(\\s|^)'+skip+'(\\s|$)'),' ').replace(/[\s]*([\S]+)+[\s]*/gi,prefix+"$1 ") : ''; 467 }, 468 getElementsBySelector: function(selector, scope) { 469 if(typeof document.querySelectorAll === 'function') { 470 return (scope || document).querySelectorAll(selector); 471 } 472 var selectors = selector.split(','); 473 var resultList = []; 474 for(var s = 0; s < selectors.length; s++) { 475 var currentContext = [scope || document]; 476 var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' '); 477 for (var i = 0; i < tokens.length; i++) { 478 token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,''); 479 if (token.indexOf('#') > -1) { 480 var bits = token.split('#'), tagName = bits[0], id = bits[1]; 481 var element = document.getElementById(id); 482 if (tagName && element.nodeName.toLowerCase() != tagName) { 483 return []; 484 } 485 currentContext = [element]; 486 continue; 487 } 488 if (token.indexOf('.') > -1) { 489 var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0; 490 for (var h = 0; h < currentContext.length; h++) { 491 var elements; 492 if (tagName == '*') { 493 elements = currentContext[h].getElementsByTagName('*'); 494 } else { 495 elements = currentContext[h].getElementsByTagName(tagName); 496 } 497 for (var j = 0; j < elements.length; j++) { 498 found[foundCount++] = elements[j]; 499 } 500 } 501 currentContext = []; 502 var currentContextIndex = 0; 503 for (var k = 0; k < found.length; k++) { 504 if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) { 505 currentContext[currentContextIndex++] = found[k]; 506 } 507 } 508 continue; 509 } 510 if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) { 511 var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4; 512 if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) { 513 attrName = 'htmlFor'; 514 } 515 var found = [], foundCount = 0; 516 for (var h = 0; h < currentContext.length; h++) { 517 var elements; 518 if (tagName == '*') { 519 elements = currentContext[h].getElementsByTagName('*'); 520 } else { 521 elements = currentContext[h].getElementsByTagName(tagName); 522 } 523 for (var j = 0; elements[j]; j++) { 524 found[foundCount++] = elements[j]; 525 } 526 } 527 currentContext = []; 528 var currentContextIndex = 0, checkFunction; 529 switch (attrOperator) { 530 case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break; 531 case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break; 532 case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break; 533 case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break; 534 case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break; 535 case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break; 536 default : checkFunction = function(e) { return e.getAttribute(attrName) }; 537 } 538 currentContext = []; 539 var currentContextIndex = 0; 540 for (var k = 0; k < found.length; k++) { 541 if (checkFunction(found[k])) { 542 currentContext[currentContextIndex++] = found[k]; 543 } 544 } 545 continue; 546 } 547 tagName = token; 548 var found = [], foundCount = 0; 549 for (var h = 0; h < currentContext.length; h++) { 550 var elements = currentContext[h].getElementsByTagName(tagName); 551 for (var j = 0; j < elements.length; j++) { 552 found[foundCount++] = elements[j]; 553 } 554 } 555 currentContext = found; 556 } 557 resultList = [].concat(resultList,currentContext); 558 } 559 return resultList; 560 }, 561 scrollSize: (function(){ 562 var content, hold, sizeBefore, sizeAfter; 563 function buildSizer(){ 564 if(hold) removeSizer(); 565 content = document.createElement('div'); 566 hold = document.createElement('div'); 567 hold.style.cssText = 'position:absolute;overflow:hidden;width:100px;height:100px'; 568 hold.appendChild(content); 569 document.body.appendChild(hold); 570 } 571 function removeSizer(){ 572 document.body.removeChild(hold); 573 hold = null; 574 } 575 function calcSize(vertical) { 576 buildSizer(); 577 content.style.cssText = 'height:'+(vertical ? '100%' : '200px'); 578 sizeBefore = (vertical ? content.offsetHeight : content.offsetWidth); 579 hold.style.overflow = 'scroll'; content.innerHTML = 1; 580 sizeAfter = (vertical ? content.offsetHeight : content.offsetWidth); 581 if(vertical && hold.clientHeight) sizeAfter = hold.clientHeight; 582 removeSizer(); 583 return sizeBefore - sizeAfter; 584 } 585 return { 586 getWidth:function(){ 587 return calcSize(false); 588 }, 589 getHeight:function(){ 590 return calcSize(true) 591 } 592 } 593 }()), 594 domReady: function (handler){ 595 var called = false 596 function ready() { 597 if (called) return; 598 called = true; 599 handler(); 600 } 601 if (document.addEventListener) { 602 document.addEventListener("DOMContentLoaded", ready, false); 603 } else if (document.attachEvent) { 604 if (document.documentElement.doScroll && window == window.top) { 605 function tryScroll(){ 606 if (called) return 607 if (!document.body) return 608 try { 609 document.documentElement.doScroll("left") 610 ready() 611 } catch(e) { 612 setTimeout(tryScroll, 0) 613 } 614 } 615 tryScroll() 616 } 617 document.attachEvent("onreadystatechange", function(){ 618 if (document.readyState === "complete") { 619 ready() 620 } 621 }) 622 } 623 if (window.addEventListener) window.addEventListener('load', ready, false) 624 else if (window.attachEvent) window.attachEvent('onload', ready) 625 }, 626 event: (function(){ 627 var guid = 0; 628 function fixEvent(e) { 629 e = e || window.event; 630 if (e.isFixed) { 631 return e; 632 } 633 e.isFixed = true; 634 e.preventDefault = e.preventDefault || function(){this.returnValue = false} 635 e.stopPropagation = e.stopPropagaton || function(){this.cancelBubble = true} 636 if (!e.target) { 637 e.target = e.srcElement 638 } 639 if (!e.relatedTarget && e.fromElement) { 640 e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement; 641 } 642 if (e.pageX == null && e.clientX != null) { 643 var html = document.documentElement, body = document.body; 644 e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0); 645 e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0); 646 } 647 if (!e.which && e.button) {
648 e.which = e.button & 1 ? 1 : (e.button & 2 ? 3 : (e.button & 4 ? 2 : 0)); 649 } 650 if(e.type === "DOMMouseScroll" || e.type === 'mousewheel') { 651 e.mWheelDelta = 0; 652 if (e.wheelDelta) { 653 e.mWheelDelta = e.wheelDelta/120; 654 } else if (e.detail) { 655 e.mWheelDelta = -e.detail/3; 656 } 657 } 658 return e; 659 } 660 function commonHandle(event, customScope) { 661 event = fixEvent(event); 662 var handlers = this.events[event.type]; 663 for (var g in handlers) { 664 var handler = handlers[g]; 665 var ret = handler.call(customScope || this, event); 666 if (ret === false) { 667 event.preventDefault() 668 event.stopPropagation() 669 } 670 } 671 } 672 var publicAPI = { 673 add: function(elem, type, handler, forcedScope) { 674 if (elem.setInterval && (elem != window && !elem.frameElement)) { 675 elem = window; 676 } 677 if (!handler.guid) { 678 handler.guid = ++guid; 679 } 680 if (!elem.events) { 681 elem.events = {}; 682 elem.handle = function(event) { 683 return commonHandle.call(elem, event); 684 } 685 } 686 if (!elem.events[type]) { 687 elem.events[type] = {}; 688 if (elem.addEventListener) elem.addEventListener(type, elem.handle, false); 689 else if (elem.attachEvent) elem.attachEvent("on" + type, elem.handle); 690 if(type === 'mousewheel') { 691 publicAPI.add(elem, 'DOMMouseScroll', handler, forcedScope); 692 } 693 } 694 var fakeHandler = jcf.lib.bind(handler, forcedScope); 695 fakeHandler.guid = handler.guid; 696 elem.events[type][handler.guid] = forcedScope ? fakeHandler : handler; 697 }, 698 remove: function(elem, type, handler) { 699 var handlers = elem.events && elem.events[type]; 700 if (!handlers) return; 701 delete handlers[handler.guid]; 702 for(var any in handlers) return; 703 if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false); 704 else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle); 705 delete elem.events[type]; 706 for (var any in elem.events) return; 707 try { 708 delete elem.handle; 709 delete elem.events; 710 } catch(e) { 711 if(elem.removeAttribute) { 712 elem.removeAttribute("handle"); 713 elem.removeAttribute("events"); 714 } 715 } 716 if(type === 'mousewheel') { 717 publicAPI.remove(elem, 'DOMMouseScroll', handler); 718 } 719 } 720 } 721 return publicAPI; 722 }()) 723} 724 725// init jcf styles 726jcf.lib.domReady(function(){ 727 jcf.initStyles(); 728});
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.