1// page init 2jQuery(function(){ 3 //jcf.customForms.replaceAll(); 4 //initCarousel(); 5 //initSlideShow(); 6 //initAccordion(); 7 //initInputs(); 8 //initSameHeight(); 9}); 10 11// scroll galleries init 12function initCarousel() { 13 jQuery('div.testimonials-gallery').scrollGallery({ 14 mask: 'div.mask', 15 slider: '> ul', 16 slides: '> li', 17 btnPrev: 'a.btn-prev', 18 btnNext: 'a.btn-next', 19 generatePagination: 'div.switcher', 20 stretchSlideToMask: true, 21 autoRotation: false, 22 switchTime: 3000, 23 animSpeed: 500 24 }); 25 jQuery('div.slide-gallery').scrollGallery({ 26 mask: 'div.mask', 27 slider: '> ul', 28 slides: '> li', 29 btnPrev: 'a.btn-prev', 30 btnNext: 'a.btn-next', 31 generatePagination: 'div.switcher', 32 stretchSlideToMask: true, 33 circularRotation: false, 34 autoRotation: false, 35 switchTime: 3000, 36 animSpeed: 500 37 }); 38} 39 40// fade gallery init 41function initSlideShow() { 42 jQuery('div.main-gallery').fadeGallery({ 43 slides: '.slides li', 44 pagerLinks: 'ul.switcher li', 45 event: 'mouseenter', 46 disableWhileAnimating: true, 47 autoRotation: false, 48 autoHeight: true, 49 switchTime: 3000, 50 animSpeed: 500 51 }); 52} 53 54// accordion menu init 55function initAccordion() { 56 jQuery('ul.accordion').slideAccordion({ 57 opener: 'a.opener', 58 slider: 'div.slide', 59 animSpeed: 300 60 }); 61} 62 63// clear inputs on focus 64function initInputs() { 65 PlaceholderInput.replaceByOptions({ 66 // filter options 67 clearInputs: false, 68 clearTextareas: false, 69 clearPasswords: true, 70 skipClass: 'default', 71 72 // input options 73 wrapWithElement: false, 74 showUntilTyping: false, 75 getParentByClass: false, 76 placeholderAttr: 'value' 77 }); 78} 79 80// align blocks height 81function initSameHeight() { 82 jQuery('div.two-columns').sameHeight({ 83 elements: 'div.column', 84 useMinHeight: true 85 }); 86 jQuery('div.twocolumns').sameHeight({ 87 elements: 'div.column', 88 useMinHeight: true 89 }); 90 jQuery('#footer .frame').sameHeight({ 91 elements: 'div.column', 92 useMinHeight: true 93 }); 94} 95 96/* 97 * jQuery Carousel plugin 98 */ 99;(function($){ 100 function ScrollGallery(options) { 101 this.options = $.extend({ 102 mask: 'div.mask', 103 slider: '>*', 104 slides: '>*', 105 activeClass:'active', 106 disabledClass:'disabled', 107 btnPrev: 'a.btn-prev', 108 btnNext: 'a.btn-next', 109 generatePagination: false, 110 pagerList: '<ul>', 111 pagerListItem: '<li><a href="#"></a></li>', 112 pagerListItemText: 'a', 113 pagerLinks: '.pagination li', 114 currentNumber: 'span.current-num', 115 totalNumber: 'span.total-num', 116 btnPlay: '.btn-play', 117 btnPause: '.btn-pause', 118 btnPlayPause: '.btn-play-pause', 119 autorotationActiveClass: 'autorotation-active', 120 autorotationDisabledClass: 'autorotation-disabled', 121 stretchSlideToMask: false, 122 circularRotation: true, 123 disableWhileAnimating: false, 124 autoRotation: false, 125 pauseOnHover: isTouchDevice ? false : true, 126 maskAutoSize: false, 127 switchTime: 4000, 128 animSpeed: 600, 129 event:'click', 130 swipeGap: false, 131 swipeThreshold: 50, 132 handleTouch: true, 133 vertical: false, 134 useTranslate3D: false, 135 step: false 136 }, options); 137 this.init(); 138 } 139 ScrollGallery.prototype = { 140 init: function() { 141 if(this.options.holder) { 142 this.findElements(); 143 this.attachEvents(); 144 this.refreshPosition(); 145 this.refreshState(true); 146 this.resumeRotation(); 147 this.makeCallback('onInit', this); 148 } 149 }, 150 findElements: function() { 151 // define dimensions proporties 152 this.fullSizeFunction = this.options.vertical ? 'outerHeight' : 'outerWidth'; 153 this.innerSizeFunction = this.options.vertical ? 'height' : 'width'; 154 this.slideSizeFunction = 'outerHeight'; 155 this.maskSizeProperty = 'height'; 156 this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft'; 157 this.swipeProperties = this.options.vertical ? ['up', 'down'] : ['left', 'right']; 158 159 // control elements 160 this.gallery = $(this.options.holder); 161 this.mask = this.gallery.find(this.options.mask); 162 this.slider = this.mask.find(this.options.slider); 163 this.slides = this.slider.find(this.options.slides); 164 this.btnPrev = this.gallery.find(this.options.btnPrev); 165 this.btnNext = this.gallery.find(this.options.btnNext); 166 this.currentStep = 0; this.stepsCount = 0; 167 168 // get start index 169 if(this.options.step === false) { 170 var activeSlide = this.slides.filter('.'+this.options.activeClass); 171 if(activeSlide.length) { 172 this.currentStep = this.slides.index(activeSlide); 173 } 174 } 175 176 // calculate offsets 177 this.calculateOffsets(); 178 $(window).bind('load resize orientationchange', $.proxy(this.onWindowResize, this)); 179 180 // create gallery pagination 181 if(typeof this.options.generatePagination === 'string') { 182 this.pagerLinks = $(); 183 this.buildPagination(); 184 } else { 185 this.pagerLinks = this.gallery.find(this.options.pagerLinks); 186 this.attachPaginationEvents(); 187 } 188 189 // autorotation control buttons 190 this.btnPlay = this.gallery.find(this.options.btnPlay); 191 this.btnPause = this.gallery.find(this.options.btnPause); 192 this.btnPlayPause = this.gallery.find(this.options.btnPlayPause); 193 194 // misc elements 195 this.curNum = this.gallery.find(this.options.currentNumber); 196 this.allNum = this.gallery.find(this.options.totalNumber); 197 }, 198 attachEvents: function() { 199 this.btnPrev.bind(this.options.event, this.bindScope(function(e){ 200 this.prevSlide(); 201 e.preventDefault(); 202 })); 203 this.btnNext.bind(this.options.event, this.bindScope(function(e){ 204 this.nextSlide(); 205 e.preventDefault(); 206 })); 207 208 // pause on hover handling 209 if(this.options.pauseOnHover) { 210 this.gallery.hover(this.bindScope(function(){ 211 if(this.options.autoRotation) { 212 this.galleryHover = true; 213 this.pauseRotation(); 214 } 215 }), this.bindScope(function(){ 216 if(this.options.autoRotation) { 217 this.galleryHover = false;
218 this.resumeRotation(); 219 } 220 })); 221 } 222 223 // autorotation buttons handler 224 this.btnPlay.bind(this.options.event, this.bindScope(this.startRotation)); 225 this.btnPause.bind(this.options.event, this.bindScope(this.stopRotation)); 226 this.btnPlayPause.bind(this.options.event, this.bindScope(function(){ 227 if(!this.gallery.hasClass(this.options.autorotationActiveClass)) { 228 this.startRotation(); 229 } else { 230 this.stopRotation(); 231 } 232 })); 233 234 // swipe event handling 235 if(isTouchDevice) { 236 // enable hardware acceleration 237 if(this.options.useTranslate3D) { 238 this.slider.css({'-webkit-transform': 'translate3d(0px, 0px, 0px)'}); 239 } 240 241 // swipe gestures 242 if(this.options.handleTouch && $.fn.swipe) { 243 this.mask.swipe({ 244 fallbackToMouseEvents: false, 245 threshold: this.options.swipeThreshold, 246 allowPageScroll: 'vertical', 247 swipeStatus: $.proxy(function(e, phase, direction, distance) { 248 if(phase === 'start') { 249 this.originalOffset = parseInt(this.slider.stop(true, false).css(this.animProperty)); 250 } else if(phase === 'move') { 251 if(direction === this.swipeProperties[0] || direction === this.swipeProperties[1]) { 252 var tmpOffset = this.originalOffset + distance * (direction === this.swipeProperties[0] ? -1 : 1); 253 if(!this.options.swipeGap) { 254 tmpOffset = Math.max(Math.min(0, tmpOffset), this.maxOffset); 255 } 256 this.tmpProps = {}; 257 this.tmpProps[this.animProperty] = tmpOffset; 258 this.slider.css(this.tmpProps); 259 e.preventDefault(); 260 } 261 } else if(phase === 'cancel') { 262 // return to previous position 263 this.switchSlide(); 264 } 265 },this), 266 swipe: $.proxy(function(event, direction) { 267 if(direction === this.swipeProperties[0]) { 268 if(this.currentStep === this.stepsCount - 1) this.switchSlide(); 269 else this.nextSlide(); 270 } else if(direction === this.swipeProperties[1]) { 271 if(this.currentStep === 0) this.switchSlide(); 272 else this.prevSlide(); 273 } 274 },this) 275 }); 276 } 277 } 278 }, 279 onWindowResize: function() { 280 if(!this.galleryAnimating) { 281 this.calculateOffsets(); 282 this.refreshPosition(); 283 this.buildPagination(); 284 this.refreshState(); 285 this.resizeQueue = false; 286 } else { 287 this.resizeQueue = true; 288 } 289 }, 290 refreshPosition: function() { 291 this.currentStep = Math.min(this.currentStep, this.stepsCount - 1); 292 this.tmpProps = {}; 293 this.tmpProps[this.animProperty] = this.getStepOffset(); 294 this.slider.stop().css(this.tmpProps); 295 }, 296 calculateOffsets: function() { 297 if(this.options.stretchSlideToMask) { 298 var tmpObj = {}; 299 tmpObj[this.innerSizeFunction] = this.mask[this.innerSizeFunction](); 300 this.slides.css(tmpObj); 301 } 302 303 this.maskSize = this.mask[this.innerSizeFunction](); 304 this.sumSize = this.getSumSize(); 305 this.maxOffset = this.maskSize - this.sumSize; 306 307 // vertical gallery with single size step custom behavior 308 if(this.options.vertical && this.options.maskAutoSize) { 309 this.options.step = 1; 310 this.stepsCount = this.slides.length; 311 this.stepOffsets = [0]; 312 var tmpOffset = 0; 313 for(var i = 0; i < this.slides.length; i++) { 314 tmpOffset -= $(this.slides[i])[this.fullSizeFunction](true); 315 this.stepOffsets.push(tmpOffset); 316 } 317 this.maxOffset = tmpOffset; 318 return; 319 } 320 321 // scroll by slide size 322 if(typeof this.options.step === 'number' && this.options.step > 0) { 323 this.slideDimensions = []; 324 this.slides.each($.proxy(function(ind, obj){ 325 this.slideDimensions.push( $(obj)[this.fullSizeFunction](true) ); 326 },this)); 327 328 // calculate steps count 329 this.stepOffsets = [0]; 330 this.stepsCount = 1; 331 var tmpOffset = 0, tmpStep = 0; 332 while(tmpOffset > this.maxOffset) { 333 tmpOffset -= this.getSlideSize(tmpStep, tmpStep + this.options.step); 334 tmpStep += this.options.step; 335 this.stepOffsets.push(Math.max(tmpOffset, this.maxOffset)); 336 this.stepsCount++; 337 } 338 } 339 // scroll by mask size 340 else { 341 // define step size 342 this.stepSize = this.maskSize; 343 344 // calculate steps count 345 this.stepsCount = 1; 346 var tmpOffset = 0; 347 while(tmpOffset > this.maxOffset) { 348 tmpOffset -= this.stepSize; 349 this.stepsCount++; 350 } 351 } 352 },
353 getSumSize: function() { 354 var sum = 0; 355 this.slides.each($.proxy(function(ind, obj){ 356 sum += $(obj)[this.fullSizeFunction](true); 357 },this)); 358 this.slider.css(this.innerSizeFunction, sum); 359 return sum; 360 }, 361 getStepOffset: function(step) { 362 step = step || this.currentStep; 363 if(typeof this.options.step === 'number') { 364 return this.stepOffsets[this.currentStep]; 365 } else { 366 return Math.max(-this.currentStep * this.stepSize, this.maxOffset); 367 } 368 }, 369 getSlideSize: function(i1, i2) { 370 var sum = 0; 371 for(var i = i1; i < Math.min(i2, this.slideDimensions.length); i++) { 372 sum += this.slideDimensions[i]; 373 } 374 return sum; 375 }, 376 buildPagination: function() { 377 if(typeof this.options.generatePagination === 'string') { 378 if(!this.pagerHolder) { 379 this.pagerHolder = this.gallery.find(this.options.generatePagination); 380 } 381 if(this.pagerHolder.length && this.oldStepsCount != this.stepsCount) { 382 this.oldStepsCount = this.stepsCount; 383 this.pagerHolder.empty(); 384 this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder); 385 for(var i = 0; i < this.stepsCount; i++) { 386 $(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1); 387 } 388 this.pagerLinks = this.pagerList.children(); 389 this.attachPaginationEvents(); 390 } 391 } 392 }, 393 attachPaginationEvents: function() { 394 this.pagerLinks.each(this.bindScope(function(ind, obj){ 395 $(obj).bind(this.options.event, this.bindScope(function(){ 396 this.numSlide(ind); 397 return false; 398 })); 399 })); 400 }, 401 prevSlide: function() { 402 if(!(this.options.disableWhileAnimating && this.galleryAnimating)) { 403 if(this.currentStep > 0) { 404 this.currentStep--; 405 this.switchSlide(); 406 } else if(this.options.circularRotation) { 407 this.currentStep = this.stepsCount - 1; 408 this.switchSlide(); 409 } 410 } 411 }, 412 nextSlide: function(fromAutoRotation) { 413 if(!(this.options.disableWhileAnimating && this.galleryAnimating)) { 414 if(this.currentStep < this.stepsCount - 1) { 415 this.currentStep++; 416 this.switchSlide(); 417 } else if(this.options.circularRotation || fromAutoRotation === true) { 418 this.currentStep = 0; 419 this.switchSlide(); 420 } 421 } 422 }, 423 numSlide: function(c) { 424 if(this.currentStep != c) { 425 this.currentStep = c; 426 this.switchSlide(); 427 } 428 }, 429 switchSlide: function() { 430 this.galleryAnimating = true; 431 this.tmpProps = {} 432 this.tmpProps[this.animProperty] = this.getStepOffset(); 433 this.slider.stop().animate(this.tmpProps,{duration: this.options.animSpeed, complete: this.bindScope(function(){ 434 // animation complete 435 this.galleryAnimating = false; 436 if(this.resizeQueue) { 437 this.onWindowResize(); 438 } 439 440 // onchange callback 441 this.makeCallback('onChange', this); 442 this.autoRotate(); 443 })}); 444 this.refreshState(); 445 446 // onchange callback 447 this.makeCallback('onBeforeChange', this); 448 }, 449 refreshState: function(initial) { 450 if(this.options.step === 1 || this.stepsCount === this.slides.length) { 451 this.slides.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass); 452 } 453 this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass); 454 this.curNum.html(this.currentStep+1); 455 this.allNum.html(this.stepsCount); 456 457 // initial refresh 458 if(this.options.maskAutoSize && typeof this.options.step === 'number') { 459 this.tmpProps = {}; 460 this.tmpProps[this.maskSizeProperty] = this.slides.eq(Math.min(this.currentStep,this.slides.length-1))[this.slideSizeFunction](true); 461 this.mask.stop()[initial ? 'css' : 'animate'](this.tmpProps); 462 } 463 464 // disabled state 465 if(!this.options.circularRotation) { 466 this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass); 467 if(this.currentStep === 0) this.btnPrev.addClass(this.options.disabledClass); 468 if(this.currentStep === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass); 469 } 470 }, 471 startRotation: function() { 472 this.options.autoRotation = true; 473 this.galleryHover = false;
474 this.autoRotationStopped = false; 475 this.resumeRotation(); 476 }, 477 stopRotation: function() { 478 this.galleryHover = true; 479 this.autoRotationStopped = true; 480 this.pauseRotation(); 481 }, 482 pauseRotation: function() { 483 this.gallery.addClass(this.options.autorotationDisabledClass); 484 this.gallery.removeClass(this.options.autorotationActiveClass); 485 clearTimeout(this.timer); 486 }, 487 resumeRotation: function() { 488 if(!this.autoRotationStopped) { 489 this.gallery.addClass(this.options.autorotationActiveClass); 490 this.gallery.removeClass(this.options.autorotationDisabledClass); 491 this.autoRotate(); 492 } 493 }, 494 autoRotate: function() { 495 clearTimeout(this.timer); 496 if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) { 497 this.timer = setTimeout(this.bindScope(function(){ 498 this.nextSlide(true); 499 }), this.options.switchTime); 500 } else { 501 this.pauseRotation(); 502 } 503 }, 504 bindScope: function(func, scope) { 505 return $.proxy(func, scope || this); 506 }, 507 makeCallback: function(name) { 508 if(typeof this.options[name] === 'function') { 509 var args = Array.prototype.slice.call(arguments); 510 args.shift(); 511 this.options[name].apply(this, args); 512 } 513 } 514 }; 515 516 // detect device type 517 var isTouchDevice = (function() { 518 try { 519 return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; 520 } catch (e) { 521 return false; 522 } 523 }()); 524 525 // jquery plugin 526 $.fn.scrollGallery = function(opt){ 527 return this.each(function(){ 528 $(this).data('ScrollGallery', new ScrollGallery($.extend(opt,{holder:this}))); 529 }); 530 }; 531}(jQuery)); 532 533/* 534 * jQuery SlideShow plugin 535 */ 536;(function($){ 537 function FadeGallery(options) { 538 this.options = $.extend({ 539 slides: 'ul.slideset > li', 540 activeClass:'active', 541 disabledClass:'disabled', 542 btnPrev: 'a.btn-prev', 543 btnNext: 'a.btn-next', 544 generatePagination: false, 545 pagerList: '<ul>', 546 pagerListItem: '<li><a href="#"></a></li>', 547 pagerListItemText: 'a', 548 pagerLinks: '.pagination li', 549 currentNumber: 'span.current-num', 550 totalNumber: 'span.total-num', 551 btnPlay: '.btn-play', 552 btnPause: '.btn-pause', 553 btnPlayPause: '.btn-play-pause', 554 autorotationActiveClass: 'autorotation-active', 555 autorotationDisabledClass: 'autorotation-disabled', 556 autorotationStopAfterClick: false, 557 circularRotation: true, 558 switchSimultaneously: true, 559 disableWhileAnimating: false, 560 disableFadeIE: false, 561 autoRotation: false, 562 pauseOnHover: true, 563 autoHeight: false, 564 useSwipe: false, 565 switchTime: 4000, 566 animSpeed: 600, 567 event:'click' 568 }, options); 569 this.init(); 570 } 571 FadeGallery.prototype = { 572 init: function() { 573 if(this.options.holder) { 574 this.findElements(); 575 this.initStructure(); 576 this.attachEvents(); 577 this.refreshState(true); 578 this.autoRotate(); 579 this.makeCallback('onInit', this); 580 } 581 }, 582 findElements: function() { 583 // control elements 584 this.gallery = $(this.options.holder); 585 this.slides = this.gallery.find(this.options.slides); 586 this.slidesHolder = this.slides.eq(0).parent(); 587 this.stepsCount = this.slides.length; 588 this.btnPrev = this.gallery.find(this.options.btnPrev); 589 this.btnNext = this.gallery.find(this.options.btnNext); 590 this.currentIndex = 0; 591 592 // disable fade effect in old IE 593 if(this.options.disableFadeIE && $.browser.msie && $.browser.version < 9) { 594 this.options.animSpeed = 0; 595 } 596 597 // create gallery pagination 598 if(typeof this.options.generatePagination === 'string') { 599 this.pagerHolder = this.gallery.find(this.options.generatePagination).empty(); 600 this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder); 601 for(var i = 0; i < this.stepsCount; i++) { 602 $(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1); 603 } 604 this.pagerLinks = this.pagerList.children(); 605 } else { 606 this.pagerLinks = this.gallery.find(this.options.pagerLinks); 607 } 608 609 // get start index 610 var activeSlide = this.slides.filter('.'+this.options.activeClass); 611 if(activeSlide.length) { 612 this.currentIndex = this.slides.index(activeSlide); 613 } 614 this.prevIndex = this.currentIndex; 615 616 // autorotation control buttons 617 this.btnPlay = this.gallery.find(this.options.btnPlay); 618 this.btnPause = this.gallery.find(this.options.btnPause); 619 this.btnPlayPause = this.gallery.find(this.options.btnPlayPause); 620 621 // misc elements 622 this.curNum = this.gallery.find(this.options.currentNumber); 623 this.allNum = this.gallery.find(this.options.totalNumber); 624 625 // handle flexible layout 626 $(window).bind('load resize orientationchange', $.proxy(this.onWindowResize, this)); 627 }, 628 initStructure: function() { 629 this.slides.css({display:'block',opacity:0}
629).eq(this.currentIndex).css({ 630 opacity:'' 631 }); 632 }, 633 attachEvents: function() { 634 var self = this; 635 this.btnPrev.bind(this.options.event, function(e){ 636 self.prevSlide(); 637 if(self.options.autorotationStopAfterClick) { 638 self.stopRotation(); 639 } 640 e.preventDefault(); 641 }); 642 this.btnNext.bind(this.options.event, function(e){ 643 self.nextSlide(); 644 if(self.options.autorotationStopAfterClick) { 645 self.stopRotation(); 646 } 647 e.preventDefault(); 648 }); 649 this.pagerLinks.each(function(ind, obj){ 650 $(obj).bind(self.options.event, function(e){ 651 self.numSlide(ind); 652 if(self.options.autorotationStopAfterClick) { 653 self.stopRotation(); 654 } 655 e.preventDefault(); 656 }); 657 }); 658 659 // autorotation buttons handler 660 this.btnPlay.bind(this.options.event, function(e){ 661 self.startRotation(); 662 e.preventDefault(); 663 }); 664 this.btnPause.bind(this.options.event, function(e){ 665 self.stopRotation(); 666 e.preventDefault(); 667 }); 668 this.btnPlayPause.bind(this.options.event, function(e){ 669 if(!self.gallery.hasClass(self.options.autorotationActiveClass)) { 670 self.startRotation(); 671 } else { 672 self.stopRotation(); 673 } 674 e.preventDefault(); 675 }); 676 677 // swipe gestures handler 678 if(this.options.useSwipe && $.fn.swipe) { 679 this.gallery.swipe({ 680 fallbackToMouseEvents: false, 681 swipeLeft: function() { 682 self.nextSlide(); 683 }, 684 swipeRight: function() { 685 self.prevSlide(); 686 } 687 }); 688 } 689 690 // pause on hover handling 691 if(this.options.pauseOnHover) { 692 this.gallery.hover(function(){ 693 if(self.options.autoRotation) { 694 self.galleryHover = true; 695 self.pauseRotation(); 696 } 697 }, function(){ 698 if(self.options.autoRotation) { 699 self.galleryHover = false; 700 self.resumeRotation(); 701 } 702 }); 703 } 704 }, 705 onWindowResize: function(){ 706 if(this.options.autoHeight) { 707 this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) }); 708 } 709 }, 710 prevSlide: function() { 711 if(!(this.options.disableWhileAnimating && this.galleryAnimating)) { 712 this.prevIndex = this.currentIndex; 713 if(this.currentIndex > 0) { 714 this.currentIndex--; 715 this.switchSlide(); 716 } else if(this.options.circularRotation) { 717 this.currentIndex = this.stepsCount - 1; 718 this.switchSlide(); 719 } 720 } 721 }, 722 nextSlide: function(fromAutoRotation) { 723 if(!(this.options.disableWhileAnimating && this.galleryAnimating)) { 724 this.prevIndex = this.currentIndex; 725 if(this.currentIndex < this.stepsCount - 1) { 726 this.currentIndex++; 727 this.switchSlide(); 728 } else if(this.options.circularRotation || fromAutoRotation === true) { 729 this.currentIndex = 0; 730 this.switchSlide(); 731 } 732 } 733 }, 734 numSlide: function(c) { 735 if(this.currentIndex != c) { 736 this.prevIndex = this.currentIndex; 737 this.currentIndex = c; 738 this.switchSlide(); 739 } 740 }, 741 switchSlide: function() { 742 var self = this; 743 if(this.slides.length > 1) { 744 this.galleryAnimating = true; 745 if(!this.options.animSpeed) { 746 this.slides.eq(this.prevIndex).css({opacity:0}); 747 } else { 748 this.slides.eq(this.prevIndex).stop().animate({opacity:0}
748,{duration: this.options.animSpeed}); 749 } 750 751 this.switchNext = function() { 752 if(!self.options.animSpeed) { 753 self.slides.eq(self.currentIndex).css({opacity:''}); 754 } else { 755 self.slides.eq(self.currentIndex).stop().animate({opacity:1},{duration: self.options.animSpeed}); 756 } 757 setTimeout(function() { 758 self.slides.eq(self.currentIndex).css({opacity:''}); 759 self.galleryAnimating = false; 760 self.autoRotate(); 761 762 // onchange callback 763 self.makeCallback('onChange', self); 764 }, self.options.animSpeed); 765 } 766 767 if(this.options.switchSimultaneously) { 768 self.switchNext(); 769 } else { 770 clearTimeout(this.switchTimer); 771 this.switchTimer = setTimeout(function(){ 772 self.switchNext(); 773 }, this.options.animSpeed); 774 } 775 this.refreshState(); 776 777 // onchange callback 778 this.makeCallback('onBeforeChange', this); 779 } 780 }, 781 refreshState: function(initial) { 782 this.slides.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass); 783 this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass); 784 this.curNum.html(this.currentIndex+1); 785 this.allNum.html(this.stepsCount); 786 787 // initial refresh 788 if(this.options.autoHeight) { 789 if(initial) { 790 this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) }); 791 } else { 792 this.slidesHolder.stop().animate({height: this.slides.eq(this.currentIndex).outerHeight(true)}, {duration: this.options.animSpeed}); 793 } 794 } 795 796 // disabled state 797 if(!this.options.circularRotation) { 798 this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass); 799 if(this.currentIndex === 0) this.btnPrev.addClass(this.options.disabledClass); 800 if(this.currentIndex === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass); 801 } 802 }, 803 startRotation: function() { 804 this.options.autoRotation = true; 805 this.galleryHover = false; 806 this.autoRotationStopped = false; 807 this.resumeRotation(); 808 }, 809 stopRotation: function() { 810 this.galleryHover = true; 811 this.autoRotationStopped = true; 812 this.pauseRotation(); 813 }, 814 pauseRotation: function() { 815 this.gallery.addClass(this.options.autorotationDisabledClass); 816 this.gallery.removeClass(this.options.autorotationActiveClass); 817 clearTimeout(this.timer); 818 }, 819 resumeRotation: function() { 820 if(!this.autoRotationStopped) { 821 this.gallery.addClass(this.options.autorotationActiveClass); 822 this.gallery.removeClass(this.options.autorotationDisabledClass); 823 this.autoRotate(); 824 } 825 }, 826 autoRotate: function() { 827 var self = this; 828 clearTimeout(this.timer); 829 if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) { 830 this.gallery.addClass(this.options.autorotationActiveClass); 831 this.timer = setTimeout(function(){ 832 self.nextSlide(true); 833 }, this.options.switchTime); 834 } else { 835 this.pauseRotation(); 836 } 837 }, 838 makeCallback: function(name) { 839 if(typeof this.options[name] === 'function') { 840 var args = Array.prototype.slice.call(arguments); 841 args.shift(); 842 this.options[name].apply(this, args); 843 } 844 } 845 } 846 847 // jquery plugin 848 $.fn.fadeGallery = function(opt){ 849 return this.each(function(){ 850 $(this).data('FadeGallery', new FadeGallery($.extend(opt,{holder:this}))); 851 }); 852 } 853}(jQuery)); 854 855/* 856 * jQuery Accordion plugin 857 */ 858;(function($){ 859 $.fn.slideAccordion = function(opt){ 860 // default options 861 var options = $.extend({ 862 addClassBeforeAnimation: false, 863 activeClass:'active', 864 opener:'.opener', 865 slider:'.slide', 866 animSpeed: 300, 867 collapsible:true, 868 event:'click' 869 },opt); 870 871 return this.each(function(){ 872 // options 873 var accordion = $(this); 874 var items = accordion.find(':has('+options.slider+')'); 875 876 items.each(function(){ 877 var item = $(this); 878 var opener = item.find(options.opener); 879 var slider = item.find(options.slider); 880 opener.bind(options.event, function(e){ 881 if(!slider.is(':animated')) { 882 if(item.hasClass(options.activeClass)) { 883 if(options.collapsible) { 884 slider.slideUp(options.animSpeed, function(){ 885 hideSlide(slider); 886 item.removeClass(options.activeClass); 887 }); 888 } 889 } else { 890 // show active 891 var levelItems = item.siblings('.'+options.activeClass); 892 var sliderElements = levelItems.find(options.slider); 893 item.addClass(options.activeClass); 894 showSlide(slider).hide().slideDown(options.animSpeed); 895 896 // collapse others 897 sliderElements.slideUp(options.animSpeed, function(){ 898 levelItems.removeClass(options.activeClass); 899 hideSlide(sliderElements); 900 }); 901 } 902 } 903 e.preventDefault(); 904 }); 905 if(item.hasClass(options.activeClass)) showSlide(slider); else hideSlide(slider); 906 }); 907 }); 908 }; 909 910 // accordion slide visibility 911 var showSlide = function(slide) { 912 return slide.css({position:'', top: '', left: '', width: '' }); 913 }; 914 var hideSlide = function(slide) { 915 return slide.show().css({position:'absolute', top: -9999, left: -9999, width: slide.width() }); 916 }; 917}(jQuery)); 918 919/* 920 * jQuery SameHeight plugin 921 */ 922;(function($){ 923 $.fn.sameHeight = function(opt) { 924 var options = $.extend({ 925 skipClass: 'same-height-ignore', 926 leftEdgeClass: 'same-height-left', 927 rightEdgeClass: 'same-height-right', 928 elements: '>*', 929 flexible: false, 930 multiLine: false, 931 useMinHeight: false 932 },opt); 933 return this.each(function(){ 934 var holder = $(this), postResizeTimer, ignoreResize; 935 var elements = holder.find(options.elements).not('.' + options.skipClass); 936 if(!elements.length) return; 937 938 // resize handler 939 function doResize() { 940 elements.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', ''); 941 if(options.multiLine) { 942 // resize elements row by row 943 resizeElementsByRows(elements, options); 944 } else { 945 // resize elements by holder 946 resizeElements(elements, holder, options); 947 } 948 } 949 doResize(); 950 951 // handle flexible layout / font resize 952 var delayedResizeHandler = function() { 953 if(!ignoreResize) { 954 ignoreResize = true; 955 doResize(); 956 clearTimeout(postResizeTimer); 957 postResizeTimer = setTimeout(function() { 958 doResize(); 959 setTimeout(function(){ 960 ignoreResize = false;
961 }, 10); 962 }, 100); 963 } 964 }; 965 966 // handle flexible/responsive layout 967 if(options.flexible) { 968 $(window).bind('resize orientationchange fontresize', delayedResizeHandler); 969 } 970 971 // handle complete page load including images and fonts 972 $(window).bind('load', delayedResizeHandler); 973 }); 974 }; 975 976 // detect css min-height support 977 var supportMinHeight = typeof document.documentElement.style.maxHeight !== 'undefined'; 978 979 // get elements by rows 980 function resizeElementsByRows(boxes, options) { 981 var currentRow = $(), maxHeight, firstOffset = boxes.eq(0).offset().top; 982 boxes.each(function(ind){ 983 var curItem = $(this); 984 if(curItem.offset().top === firstOffset) { 985 currentRow = currentRow.add(this); 986 } else { 987 maxHeight = getMaxHeight(currentRow); 988 resizeElements(currentRow, maxHeight, options); 989 currentRow = curItem; 990 firstOffset = curItem.offset().top; 991 } 992 }); 993 if(currentRow.length) { 994 maxHeight = getMaxHeight(currentRow); 995 resizeElements(currentRow, maxHeight, options); 996 } 997 } 998 999 // calculate max element height 1000 function getMaxHeight(boxes) { 1001 var maxHeight = 0; 1002 boxes.each(function(){ 1003 maxHeight = Math.max(maxHeight, $(this).outerHeight()); 1004 }); 1005 return maxHeight; 1006 } 1007 1008 // resize helper function 1009 function resizeElements(boxes, parent, options) { 1010 var parentHeight = typeof parent === 'number' ? parent : parent.height(); 1011 boxes.removeClass(options.leftEdgeClass).removeClass(options.rightEdgeClass).each(function(i){ 1012 var element = $(this); 1013 var depthDiffHeight = 0; 1014 1015 if(typeof parent !== 'number') { 1016 element.parents().each(function(){ 1017 var tmpParent = $(this); 1018 if(this === parent[0]) { 1019 return false; 1020 } else { 1021 depthDiffHeight += tmpParent.outerHeight() - tmpParent.height(); 1022 } 1023 }); 1024 } 1025 var calcHeight = parentHeight - depthDiffHeight - (element.outerHeight() - element.height()); 1026 if(calcHeight > 0) { 1027 element.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', calcHeight); 1028 } 1029 }); 1030 boxes.filter(':first').addClass(options.leftEdgeClass); 1031 boxes.filter(':last').addClass(options.rightEdgeClass); 1032 } 1033}(jQuery)); 1034 1035/* 1036 * jQuery FontResize Event 1037 */ 1038jQuery.onFontResize = (function($) { 1039 $(function() { 1040 var randomID = 'font-resize-frame-' + Math.floor(Math.random() * 1000); 1041 var resizeFrame = $('<iframe>').attr('id', randomID).addClass('font-resize-helper'); 1042 1043 // required styles 1044 resizeFrame.css({ 1045 width: '100em', 1046 height: '10px', 1047 position: 'absolute', 1048 borderWidth: 0, 1049 top: '-9999px', 1050 left: '-9999px' 1051 }).appendTo('body'); 1052 1053 // use native IE resize event if possible 1054 if ($.browser.msie && $.browser.version < 9) { 1055 resizeFrame.bind('resize', function () { 1056 $.onFontResize.trigger(resizeFrame[0].offsetWidth / 100); 1057 }); 1058 } 1059 // use script inside the iframe to detect resize for other browsers 1060 else { 1061 var doc = resizeFrame[0].contentWindow.document; 1062 doc.open(); 1063 doc.write('<scri' + 'pt>window.onload = function(){var em = parent.jQuery("#' + randomID + '")[0];window.onresize = function(){if(parent.jQuery.onFontResize){parent.jQuery.onFontResize.trigger(em.offsetWidth / 100);}}};</scri' + 'pt>'); 1064 doc.close(); 1065 }
1066 jQuery.onFontResize.initialSize = resizeFrame[0].offsetWidth / 100; 1067 }); 1068 return { 1069 // public method, so it can be called from within the iframe 1070 trigger: function (em) { 1071 $(window).trigger("fontresize", [em]); 1072 } 1073 }; 1074}(jQuery)); 1075 1076/* 1077 * JavaScript Custom Forms Module 1078 */ 1079jcf = { 1080 // global options 1081 modules: {}, 1082 plugins: {}, 1083 baseOptions: { 1084 useNativeDropOnMobileDevices: true, 1085 unselectableClass:'jcf-unselectable', 1086 labelActiveClass:'jcf-label-active', 1087 labelDisabledClass:'jcf-label-disabled', 1088 classPrefix: 'jcf-class-', 1089 hiddenClass:'jcf-hidden', 1090 focusClass:'jcf-focus', 1091 wrapperTag: 'div' 1092 }, 1093 // replacer function 1094 customForms: { 1095 setOptions: function(obj) { 1096 for(var p in obj) { 1097 if(obj.hasOwnProperty(p) && typeof obj[p] === 'object') { 1098 jcf.lib.extend(jcf.modules[p].prototype.defaultOptions, obj[p]); 1099 } 1100 } 1101 }, 1102 replaceAll: function() { 1103 for(var k in jcf.modules) { 1104 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector); 1105 for(var i = 0; i<els.length; i++) { 1106 if(els[i].jcf) { 1107 // refresh form element state 1108 els[i].jcf.refreshState(); 1109 } else { 1110 // replace form element 1111 if(!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) { 1112 new jcf.modules[k]({ 1113 replaces:els[i] 1114 }); 1115 } 1116 } 1117 } 1118 } 1119 }, 1120 refreshAll: function() { 1121 for(var k in jcf.modules) { 1122 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector); 1123 for(var i = 0; i<els.length; i++) { 1124 if(els[i].jcf) { 1125 // refresh form element state 1126 els[i].jcf.refreshState(); 1127 } 1128 } 1129 } 1130 }, 1131 refreshElement: function(obj) { 1132 if(obj && obj.jcf) { 1133 obj.jcf.refreshState(); 1134 } 1135 }, 1136 destroyAll: function() { 1137 for(var k in jcf.modules) { 1138 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector); 1139 for(var i = 0; i<els.length; i++) { 1140 if(els[i].jcf) { 1141 els[i].jcf.destroy(); 1142 } 1143 } 1144 } 1145 } 1146 }, 1147 // detect device type 1148 isTouchDevice: (function() { 1149 try { 1150 return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; 1151 } catch (e) { 1152 return false; 1153 } 1154 }()), 1155 // define base module 1156 setBaseModule: function(obj) { 1157 jcf.customControl = function(opt){ 1158 this.options = jcf.lib.extend({}, jcf.baseOptions, this.defaultOptions, opt); 1159 this.init(); 1160 }; 1161 for(var p in obj) { 1162 jcf.customControl.prototype[p] = obj[p]; 1163 } 1164 }, 1165 // add module to jcf.modules 1166 addModule: function(obj) { 1167 if(obj.name){ 1168 // create new module proto class 1169 jcf.modules[obj.name] = function(){ 1170 jcf.modules[obj.name].superclass.constructor.apply(this, arguments); 1171 }; 1172 jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl); 1173 for(var p in obj) { 1174 jcf.modules[obj.name].prototype[p] = obj[p]; 1175 } 1176 // on create module 1177 jcf.modules[obj.name].prototype.onCreateModule(); 1178 // make callback for exciting modules 1179 for(var mod in jcf.modules) { 1180 if(jcf.modules[mod] != jcf.modules[obj.name]) { 1181 jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]); 1182 } 1183 } 1184 } 1185 }, 1186 // add plugin to jcf.plugins 1187 addPlugin: function(obj) { 1188 if(obj && obj.name) { 1189 jcf.plugins[obj.name] = function() { 1190 this.init.apply(this, arguments); 1191 }; 1192 for(var p in obj) { 1193 jcf.plugins[obj.name].prototype[p] = obj[p]; 1194 } 1195 } 1196 }, 1197 // miscellaneous init 1198 init: function(){ 1199 if(navigator.msPointerEnabled) { 1200 this.eventPress = 'MSPointerDown'; 1201 this.eventMove = 'MSPointerMove'; 1202 this.eventRelease = 'MSPointerUp'; 1203 } else { 1204 this.eventPress = this.isTouchDevice ? 'touchstart' : 'mousedown'; 1205 this.eventMove = this.isTouchDevice ? 'touchmove' : 'mousemove'; 1206 this.eventRelease = this.isTouchDevice ? 'touchend' : 'mouseup'; 1207 } 1208 1209 // init jcf styles 1210 setTimeout(function(){ 1211 jcf.lib.domReady(function(){ 1212 jcf.initStyles(); 1213 }); 1214 },1); 1215 return this; 1216 }, 1217 initStyles: function() { 1218 // create <style> element and rules 1219 var head = document.getElementsByTagName('head')[0], 1220 style = document.createElement('style'), 1221 rules = document.createTextNode('.'+jcf.baseOptions.unselectableClass+'{'+ 1222 '-moz-user-select:none;'+ 1223 '-webkit-tap-highlight-color:rgba(255,255,255,0);'+ 1224 '-webkit-user-select:none;'+ 1225 'user-select:none;'+ 1226 '}'); 1227 1228 // append style element 1229 style.type = 'text/css'; 1230 if(style.styleSheet) { 1231 style.styleSheet.cssText = rules.nodeValue; 1232 } else { 1233 style.appendChild(rules); 1234 } 1235 head.appendChild(style); 1236 } 1237}.init(); 1238 1239/* 1240 * Custom Form Control prototype 1241 */ 1242jcf.setBaseModule({ 1243 init: function(){ 1244 if(this.options.replaces) { 1245 this.realElement = this.options.replaces; 1246 this.realElement.jcf = this; 1247 this.replaceObject(); 1248 } 1249 }, 1250 defaultOptions: { 1251 // default module options (will be merged with base options) 1252 }, 1253 checkElement: function(el){ 1254 return true;
1254 // additional check for correct form element 1255 }, 1256 replaceObject: function(){ 1257 this.createWrapper(); 1258 this.attachEvents(); 1259 this.fixStyles(); 1260 this.setupWrapper(); 1261 }, 1262 createWrapper: function(){ 1263 this.fakeElement = jcf.lib.createElement(this.options.wrapperTag); 1264 this.labelFor = jcf.lib.getLabelFor(this.realElement); 1265 jcf.lib.disableTextSelection(this.fakeElement); 1266 jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.classPrefix)); 1267 jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass); 1268 }, 1269 attachEvents: function(){ 1270 jcf.lib.event.add(this.realElement, 'focus', this.onFocusHandler, this); 1271 jcf.lib.event.add(this.realElement, 'blur', this.onBlurHandler, this); 1272 jcf.lib.event.add(this.fakeElement, 'click', this.onFakeClick, this); 1273 jcf.lib.event.add(this.fakeElement, jcf.eventPress, this.onFakePressed, this); 1274 jcf.lib.event.add(this.fakeElement, jcf.eventRelease, this.onFakeReleased, this); 1275 1276 if(this.labelFor) { 1277 this.labelFor.jcf = this; 1278 jcf.lib.event.add(this.labelFor, 'click', this.onFakeClick, this); 1279 jcf.lib.event.add(this.labelFor, jcf.eventPress, this.onFakePressed, this); 1280 jcf.lib.event.add(this.labelFor, jcf.eventRelease, this.onFakeReleased, this); 1281 } 1282 }, 1283 fixStyles: function() { 1284 // hide mobile webkit tap effect 1285 if(jcf.isTouchDevice) { 1286 var tapStyle = 'rgba(255,255,255,0)'; 1287 this.realElement.style.webkitTapHighlightColor = tapStyle; 1288 this.fakeElement.style.webkitTapHighlightColor = tapStyle; 1289 if(this.labelFor) { 1290 this.labelFor.style.webkitTapHighlightColor = tapStyle; 1291 } 1292 } 1293 }, 1294 setupWrapper: function(){ 1295 // implement in subclass 1296 }, 1297 refreshState: function(){ 1298 // implement in subclass 1299 }, 1300 destroy: function() { 1301 if(this.fakeElement && this.fakeElement.parentNode) { 1302 this.fakeElement.parentNode.removeChild(this.fakeElement); 1303 } 1304 jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass); 1305 this.realElement.jcf = null; 1306 }, 1307 onFocus: function(){ 1308 // emulated focus event 1309 jcf.lib.addClass(this.fakeElement,this.options.focusClass); 1310 }, 1311 onBlur: function(cb){ 1312 // emulated blur event 1313 jcf.lib.removeClass(this.fakeElement,this.options.focusClass); 1314 }, 1315 onFocusHandler: function() { 1316 // handle focus loses 1317 if(this.focused) return; 1318 this.focused = true; 1319 1320 // handle touch devices also 1321 if(jcf.isTouchDevice) { 1322 if(jcf.focusedInstance && jcf.focusedInstance.realElement != this.realElement) { 1323 jcf.focusedInstance.onBlur(); 1324 jcf.focusedInstance.realElement.blur(); 1325 } 1326 jcf.focusedInstance = this; 1327 } 1328 this.onFocus.apply(this, arguments); 1329 }, 1330 onBlurHandler: function() { 1331 // handle focus loses 1332 if(!this.pressedFlag) { 1333 this.focused = false; 1334 this.onBlur.apply(this, arguments); 1335 } 1336 }, 1337 onFakeClick: function(){ 1338 if(jcf.isTouchDevice) { 1339 this.onFocus(); 1340 } else if(!this.realElement.disabled) { 1341 this.realElement.focus(); 1342 } 1343 }, 1344 onFakePressed: function(e){ 1345 this.pressedFlag = true; 1346 }, 1347 onFakeReleased: function(){ 1348 this.pressedFlag = false; 1349 }, 1350 onCreateModule: function(){ 1351 // implement in subclass 1352 }, 1353 onModuleAdded: function(module) { 1354 // implement in subclass 1355 }, 1356 onControlReady: function() { 1357 // implement in subclass 1358 } 1359}); 1360 1361/* 1362 * JCF Utility Library 1363 */ 1364jcf.lib = { 1365 bind: function(func, scope){ 1366 return function() { 1367 return func.apply(scope, arguments); 1368 } 1369 }, 1370 browser: (function() { 1371 var ua = navigator.userAgent.toLowerCase(), res = {}, 1372 match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) || 1373 /(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || []; 1374 res[match[1]] = true; 1375 res.version = match[2] || "0"; 1376 res.safariMac = ua.indexOf('mac') != -1 && ua.indexOf('safari') != -1; 1377 return res; 1378 })(), 1379 getOffset: function (obj) { 1380 if (obj.getBoundingClientRect) { 1381 var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft; 1382 var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; 1383 var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0; 1384 var clientTop = document.documentElement.clientTop || document.body.clientTop || 0; 1385 return { 1386 top:Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop), 1387 left:Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft) 1388 } 1389 } else { 1390 var posLeft = 0, posTop = 0; 1391 while (obj.offsetParent) {posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent;}
1392 return {top:posTop,left:posLeft}; 1393 } 1394 }, 1395 getScrollTop: function() { 1396 return window.pageYOffset || document.documentElement.scrollTop; 1397 }, 1398 getScrollLeft: function() { 1399 return window.pageXOffset || document.documentElement.scrollLeft; 1400 }, 1401 getWindowWidth: function(){ 1402 return document.compatMode=='CSS1Compat' ? document.documentElement.clientWidth : document.body.clientWidth; 1403 }, 1404 getWindowHeight: function(){ 1405 return document.compatMode=='CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight; 1406 }, 1407 getStyle: function(el, prop) { 1408 if (document.defaultView && document.defaultView.getComputedStyle) { 1409 return document.defaultView.getComputedStyle(el, null)[prop]; 1410 } else if (el.currentStyle) { 1411 return el.currentStyle[prop]; 1412 } else { 1413 return el.style[prop]; 1414 } 1415 }, 1416 getParent: function(obj, selector) { 1417 while(obj.parentNode && obj.parentNode != document.body) { 1418 if(obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) { 1419 return obj.parentNode; 1420 } 1421 obj = obj.parentNode; 1422 } 1423 return false; 1424 }, 1425 isParent: function(child, parent) { 1426 while(child.parentNode) { 1427 if(child.parentNode === parent) { 1428 return true; 1429 } 1430 child = child.parentNode; 1431 } 1432 return false; 1433 }, 1434 getLabelFor: function(object) { 1435 if(jcf.lib.getParent(object,'label')) { 1436 return object.parentNode; 1437 } else if(object.id) { 1438 return jcf.lib.queryBySelector('label[for="' + object.id + '"]')[0]; 1439 } 1440 }, 1441 disableTextSelection: function(el){ 1442 if (typeof el.onselectstart !== 'undefined') { 1443 el.onselectstart = function() {return false}; 1444 } else if(window.opera) { 1445 el.setAttribute('unselectable', 'on'); 1446 } else { 1447 jcf.lib.addClass(el, jcf.baseOptions.unselectableClass); 1448 } 1449 }, 1450 enableTextSelection: function(el) { 1451 if (typeof el.onselectstart !== 'undefined') { 1452 el.onselectstart = null; 1453 } else if(window.opera) { 1454 el.removeAttribute('unselectable'); 1455 } else { 1456 jcf.lib.removeClass(el, jcf.baseOptions.unselectableClass); 1457 } 1458 }, 1459 queryBySelector: function(selector, scope){ 1460 return this.getElementsBySelector(selector, scope); 1461 }, 1462 prevSibling: function(node) { 1463 while(node = node.previousSibling) if(node.nodeType == 1) break; 1464 return node; 1465 }, 1466 nextSibling: function(node) { 1467 while(node = node.nextSibling) if(node.nodeType == 1) break; 1468 return node; 1469 }, 1470 fireEvent: function(element,event) { 1471 if(element.dispatchEvent){ 1472 var evt = document.createEvent('HTMLEvents'); 1473 evt.initEvent(event, true, true ); 1474 return !element.dispatchEvent(evt); 1475 }else if(document.createEventObject){ 1476 var evt = document.createEventObject(); 1477 return element.fireEvent('on'+event,evt); 1478 } 1479 }, 1480 isParent: function(p, c) { 1481 while(c.parentNode) { 1482 if(p == c) { 1483 return true; 1484 } 1485 c = c.parentNode; 1486 } 1487 return false; 1488 }, 1489 inherit: function(Child, Parent) { 1490 var F = function() { } 1491 F.prototype = Parent.prototype 1492 Child.prototype = new F() 1493 Child.prototype.constructor = Child 1494 Child.superclass = Parent.prototype 1495 }, 1496 extend: function(obj) { 1497 for(var i = 1; i < arguments.length; i++) { 1498 for(var p in arguments[i]) { 1499 if(arguments[i].hasOwnProperty(p)) { 1500 obj[p] = arguments[i][p]; 1501 } 1502 } 1503 } 1504 return obj; 1505 }, 1506 hasClass: function (obj,cname) { 1507 return (obj.className ? obj.className.match(new RegExp('(\\s|^)'+cname+'(\\s|$)')) : false); 1508 }, 1509 addClass: function (obj,cname) { 1510 if (!this.hasClass(obj,cname)) obj.className += (!obj.className.length || obj.className.charAt(obj.className.length - 1) === ' ' ? '' : ' ') + cname; 1511 }, 1512 removeClass: function (obj,cname) { 1513 if (this.hasClass(obj,cname)) obj.className=obj.className.replace(new RegExp('(\\s|^)'+cname+'(\\s|$)'),' ').replace(/\s+$/, ''); 1514 }, 1515 toggleClass: function(obj, cname, condition) { 1516 if(condition) this.addClass(obj, cname); else this.removeClass(obj, cname); 1517 }, 1518 createElement: function(tagName, options) { 1519 var el = document.createElement(tagName); 1520 for(var p in options) { 1521 if(options.hasOwnProperty(p)) { 1522 switch (p) { 1523 case 'class': el.className = options[p]; break; 1524 case 'html': el.innerHTML = options[p]; break; 1525 case 'style': this.setStyles(el, options[p]); break; 1526 default: el.setAttribute(p, options[p]); 1527 } 1528 } 1529 } 1530 return el; 1531 }, 1532 setStyles: function(el, styles) { 1533 for(var p in styles) { 1534 if(styles.hasOwnProperty(p)) { 1535 switch (p) { 1536 case 'float': el.style.cssFloat = styles[p]; break; 1537 case 'opacity': el.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+styles[p]*100+')'; el.style.opacity = styles[p]; break; 1538 default: el.style[p] = (typeof styles[p] === 'undefined' ? 0 : styles[p]) + (typeof styles[p] === 'number' ? 'px' : ''); 1539 } 1540 } 1541 } 1542 return el; 1543 }, 1544 getInnerWidth: function(el) { 1545 return el.offsetWidth - (parseInt(this.getStyle(el,'paddingLeft')) || 0) - (parseInt(this.getStyle(el,'paddingRight')) || 0); 1546 }, 1547 getInnerHeight: function(el) { 1548 return el.offsetHeight - (parseInt(this.getStyle(el,'paddingTop')) || 0) - (parseInt(this.getStyle(el,'paddingBottom')) || 0); 1549 }, 1550 getAllClasses: function(cname, prefix, skip) { 1551 if(!skip) skip = ''; 1552 if(!prefix) prefix = ''; 1553 return cname ? cname.replace(new RegExp('(\\s|^)'+skip+'(\\s|$)'),' ').replace(/[\s]*([\S]+)+[\s]*/gi,prefix+"$1 ") : ''; 1554 }, 1555 getElementsBySelector: function(selector, scope) { 1556 if(typeof document.querySelectorAll === 'function') { 1557 return (scope || document).querySelectorAll(selector); 1558 } 1559 var selectors = selector.split(','); 1560 var resultList = []; 1561 for(var s = 0; s < selectors.length; s++) { 1562 var currentContext = [scope || document]; 1563 var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' '); 1564 for (var i = 0; i < tokens.length; i++) { 1565 token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,''); 1566 if (token.indexOf('#') > -1) { 1567 var bits = token.split('#'), tagName = bits[0], id = bits[1]; 1568 var element = document.getElementById(id); 1569 if (tagName && element.nodeName.toLowerCase() != tagName) { 1570 return []; 1571 } 1572 currentContext = [element]; 1573 continue; 1574 } 1575 if (token.indexOf('.') > -1) { 1576 var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0; 1577 for (var h = 0; h < currentContext.length; h++) { 1578 var elements; 1579 if (tagName == '*') { 1580 elements = currentContext[h].getElementsByTagName('*'); 1581 } else { 1582 elements = currentContext[h].getElementsByTagName(tagName); 1583 } 1584 for (var j = 0; j < elements.length; j++) { 1585 found[foundCount++] = elements[j]; 1586 } 1587 } 1588 currentContext = []; 1589 var currentContextIndex = 0; 1590 for (var k = 0; k < found.length; k++) { 1591 if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) { 1592 currentContext[currentContextIndex++] = found[k]; 1593 } 1594 } 1595 continue; 1596 } 1597 if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) { 1598 var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4; 1599 if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) { 1600 attrName = 'htmlFor'; 1601 } 1602 var found = [], foundCount = 0; 1603 for (var h = 0; h < currentContext.length; h++) { 1604 var elements; 1605 if (tagName == '*') { 1606 elements = currentContext[h].getElementsByTagName('*'); 1607 } else { 1608 elements = currentContext[h].getElementsByTagName(tagName); 1609 } 1610 for (var j = 0; elements[j]; j++) { 1611 found[foundCount++] = elements[j]; 1612 } 1613 } 1614 currentContext = []; 1615 var currentContextIndex = 0, checkFunction; 1616 switch (attrOperator) { 1617 case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break; 1618 case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break; 1619 case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break; 1620 case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break; 1621 case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break; 1622 case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break; 1623 default : checkFunction = function(e) { return e.getAttribute(attrName) }; 1624 } 1625 currentContext = []; 1626 var currentContextIndex = 0; 1627 for (var k = 0; k < found.length; k++) { 1628 if (checkFunction(found[k])) { 1629 currentContext[currentContextIndex++] = found[k]; 1630 } 1631 } 1632 continue; 1633 } 1634 tagName = token; 1635 var found = [], foundCount = 0; 1636 for (var h = 0; h < currentContext.length; h++) { 1637 var elements = currentContext[h].getElementsByTagName(tagName); 1638 for (var j = 0; j < elements.length; j++) { 1639 found[foundCount++] = elements[j]; 1640 } 1641 } 1642 currentContext = found; 1643 } 1644 resultList = [].concat(resultList,currentContext); 1645 } 1646 return resultList; 1647 }, 1648 scrollSize: (function(){ 1649 var content, hold, sizeBefore, sizeAfter; 1650 function buildSizer(){ 1651 if(hold) removeSizer(); 1652 content = document.createElement('div'); 1653 hold = document.createElement('div'); 1654 hold.style.cssText = 'position:absolute;overflow:hidden;width:100px;height:100px'; 1655 hold.appendChild(content); 1656 document.body.appendChild(hold); 1657 } 1658 function removeSizer(){ 1659 document.body.removeChild(hold); 1660 hold = null; 1661 } 1662 function calcSize(vertical) { 1663 buildSizer(); 1664 content.style.cssText = 'height:'+(vertical ? '100%' : '200px'); 1665 sizeBefore = (vertical ? content.offsetHeight : content.offsetWidth); 1666 hold.style.overflow = 'scroll'; content.innerHTML = 1; 1667 sizeAfter = (vertical ? content.offsetHeight : content.offsetWidth); 1668 if(vertical && hold.clientHeight) sizeAfter = hold.clientHeight; 1669 removeSizer(); 1670 return sizeBefore - sizeAfter; 1671 } 1672 return { 1673 getWidth:function(){ 1674 return calcSize(false); 1675 }, 1676 getHeight:function(){ 1677 return calcSize(true) 1678 } 1679 } 1680 }()), 1681 domReady: function (handler){ 1682 var called = false 1683 function ready() { 1684 if (called) return; 1685 called = true; 1686 handler(); 1687 } 1688 if (document.addEventListener) { 1689 document.addEventListener("DOMContentLoaded", ready, false); 1690 } else if (document.attachEvent) { 1691 if (document.documentElement.doScroll && window == window.top) { 1692 function tryScroll(){ 1693 if (called) return 1694 if (!document.body) return 1695 try { 1696 document.documentElement.doScroll("left") 1697 ready() 1698 } catch(e) { 1699 setTimeout(tryScroll, 0) 1700 } 1701 } 1702 tryScroll() 1703 } 1704 document.attachEvent("onreadystatechange", function(){ 1705 if (document.readyState === "complete") { 1706 ready() 1707 } 1708 }) 1709 } 1710 if (window.addEventListener) window.addEventListener('load', ready, false) 1711 else if (window.attachEvent) window.attachEvent('onload', ready) 1712 }, 1713 event: (function(){ 1714 var guid = 0; 1715 function fixEvent(e) { 1716 e = e || window.event; 1717 if (e.isFixed) { 1718 return e; 1719 } 1720 e.isFixed = true; 1721 e.preventDefault = e.preventDefault || function(){this.returnValue = false} 1722 e.stopPropagation = e.stopPropagaton || function(){this.cancelBubble = true} 1723 if (!e.target) { 1724 e.target = e.srcElement 1725 } 1726 if (!e.relatedTarget && e.fromElement) { 1727 e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement; 1728 } 1729 if (e.pageX == null && e.clientX != null) { 1730 var html = document.documentElement, body = document.body; 1731 e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0); 1732 e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0); 1733 } 1734 if (!e.which && e.button) {
1735 e.which = e.button & 1 ? 1 : (e.button & 2 ? 3 : (e.button & 4 ? 2 : 0)); 1736 } 1737 if(e.type === "DOMMouseScroll" || e.type === 'mousewheel') { 1738 e.mWheelDelta = 0; 1739 if (e.wheelDelta) { 1740 e.mWheelDelta = e.wheelDelta/120; 1741 } else if (e.detail) { 1742 e.mWheelDelta = -e.detail/3; 1743 } 1744 } 1745 return e; 1746 } 1747 function commonHandle(event, customScope) { 1748 event = fixEvent(event); 1749 var handlers = this.events[event.type]; 1750 for (var g in handlers) { 1751 var handler = handlers[g]; 1752 var ret = handler.call(customScope || this, event); 1753 if (ret === false) { 1754 event.preventDefault() 1755 event.stopPropagation() 1756 } 1757 } 1758 } 1759 var publicAPI = { 1760 add: function(elem, type, handler, forcedScope) { 1761 if (elem.setInterval && (elem != window && !elem.frameElement)) { 1762 elem = window; 1763 } 1764 if (!handler.guid) { 1765 handler.guid = ++guid; 1766 } 1767 if (!elem.events) { 1768 elem.events = {}; 1769 elem.handle = function(event) { 1770 return commonHandle.call(elem, event); 1771 } 1772 } 1773 if (!elem.events[type]) { 1774 elem.events[type] = {}; 1775 if (elem.addEventListener) elem.addEventListener(type, elem.handle, false); 1776 else if (elem.attachEvent) elem.attachEvent("on" + type, elem.handle); 1777 if(type === 'mousewheel') { 1778 publicAPI.add(elem, 'DOMMouseScroll', handler, forcedScope); 1779 } 1780 } 1781 var fakeHandler = jcf.lib.bind(handler, forcedScope); 1782 fakeHandler.guid = handler.guid; 1783 elem.events[type][handler.guid] = forcedScope ? fakeHandler : handler; 1784 }, 1785 remove: function(elem, type, handler) { 1786 var handlers = elem.events && elem.events[type]; 1787 if (!handlers) return; 1788 delete handlers[handler.guid]; 1789 for(var any in handlers) return; 1790 if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false); 1791 else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle); 1792 delete elem.events[type]; 1793 for (var any in elem.events) return; 1794 try { 1795 delete elem.handle; 1796 delete elem.events; 1797 } catch(e) { 1798 if(elem.removeAttribute) { 1799 elem.removeAttribute("handle"); 1800 elem.removeAttribute("events"); 1801 } 1802 } 1803 if(type === 'mousewheel') { 1804 publicAPI.remove(elem, 'DOMMouseScroll', handler); 1805 } 1806 } 1807 } 1808 return publicAPI; 1809 }()) 1810} 1811 1812// custom select module 1813jcf.addModule({ 1814 name:'select', 1815 selector:'select', 1816 defaultOptions: { 1817 hideDropOnScroll: true, 1818 showNativeDrop: false, 1819 handleDropPosition: true, 1820 selectDropPosition: 'bottom', // or 'top' 1821 wrapperClass:'select-area', 1822 focusClass:'select-focus', 1823 dropActiveClass:'select-active', 1824 selectedClass:'item-selected', 1825 currentSelectedClass:'current-selected', 1826 disabledClass:'select-disabled', 1827 valueSelector:'span.center', 1828 optGroupClass:'optgroup', 1829 openerSelector:'a.select-opener', 1830 selectStructure:'<span class="left"></span><span class="center"></span><a class="select-opener"></a>', 1831 classPrefix:'select-', 1832 dropMaxHeight: 200, 1833 dropFlippedClass: 'select-options-flipped', 1834 dropHiddenClass:'options-hidden', 1835 dropScrollableClass:'options-overflow', 1836 dropClass:'select-options', 1837 dropClassPrefix:'drop-', 1838 dropStructure:'<div class="drop-holder"><div class="drop-list"></div></div>', 1839 dropSelector:'div.drop-list' 1840 }, 1841 checkElement: function(el){ 1842 return (!el.size && !el.multiple); 1843 }, 1844 setupWrapper: function(){ 1845 jcf.lib.addClass(this.fakeElement, this.options.wrapperClass); 1846 this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement); 1847 this.fakeElement.innerHTML = this.options.selectStructure; 1848 this.fakeElement.style.width = (this.realElement.offsetWidth > 0 ? this.realElement.offsetWidth + 'px' : 'auto'); 1849 1850 // show native drop if specified in options 1851 if(jcf.isTouchDevice && jcf.baseOptions.useNativeDropOnMobileDevices) { 1852 this.options.showNativeDrop = true; 1853 } 1854 if(this.options.showNativeDrop) { 1855 this.fakeElement.appendChild(this.realElement); 1856 jcf.lib.removeClass(this.realElement, this.options.hiddenClass); 1857 jcf.lib.setStyles(this.realElement, { 1858 top:0, 1859 left:0, 1860 margin:0, 1861 padding:0, 1862 opacity:0, 1863 border:'none', 1864 position:'absolute', 1865 width: jcf.lib.getInnerWidth(this.fakeElement) - 1, 1866 height: jcf.lib.getInnerHeight(this.fakeElement) - 1 1867 }); 1868 jcf.lib.event.add(this.realElement, 'touchstart', function(){ 1869 this.realElement.title = ''; 1870 }, this) 1871 } 1872 1873 // create select body 1874 this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0]; 1875 this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0]; 1876 jcf.lib.disableTextSelection(this.valueText); 1877 this.opener.jcf = this; 1878 1879 if(!this.options.showNativeDrop) { 1880 this.createDropdown(); 1881 this.refreshState(); 1882 this.onControlReady(this); 1883 this.hideDropdown(true); 1884 } else { 1885 this.refreshState(); 1886 } 1887 this.addEvents(); 1888 }, 1889 addEvents: function(){ 1890 if(this.options.showNativeDrop) { 1891 jcf.lib.event.add(this.realElement, 'click', this.onChange, this); 1892 } else { 1893 jcf.lib.event.add(this.fakeElement, 'click', this.toggleDropdown, this); 1894 } 1895 jcf.lib.event.add(this.realElement, 'change', this.onChange, this); 1896 }, 1897 onFakeClick: function() { 1898 // do nothing (drop toggles by toggleDropdown method) 1899 }, 1900 onFocus: function(){ 1901 jcf.modules[this.name].superclass.onFocus.apply(this, arguments); 1902 if(!this.options.showNativeDrop) { 1903 // Mac Safari Fix 1904 if(jcf.lib.browser.safariMac) { 1905 this.realElement.setAttribute('size','2'); 1906 } 1907 jcf.lib.event.add(this.realElement, 'keydown', this.onKeyDown, this); 1908 if(jcf.activeControl && jcf.activeControl != this) { 1909 jcf.activeControl.hideDropdown(); 1910 jcf.activeControl = this; 1911 } 1912 } 1913 }, 1914 onBlur: function(){ 1915 if(!this.options.showNativeDrop) { 1916 // Mac Safari Fix 1917 if(jcf.lib.browser.safariMac) { 1918 this.realElement.removeAttribute('size'); 1919 } 1920 if(!this.isActiveDrop() || !this.isOverDrop()) { 1921 jcf.modules[this.name].superclass.onBlur.apply(this); 1922 if(jcf.activeControl === this) jcf.activeControl = null; 1923 if(!jcf.isTouchDevice) { 1924 this.hideDropdown(); 1925 } 1926 } 1927 jcf.lib.event.remove(this.realElement, 'keydown', this.onKeyDown); 1928 } else { 1929 jcf.modules[this.name].superclass.onBlur.apply(this); 1930 } 1931 }, 1932 onChange: function() { 1933 this.refreshState(); 1934 }, 1935 onKeyDown: function(e){ 1936 this.dropOpened = true; 1937 jcf.tmpFlag = true; 1938 setTimeout(function(){jcf.tmpFlag = false},100); 1939 var context = this; 1940 context.keyboardFix = true; 1941 setTimeout(function(){ 1942 context.refreshState(); 1943 },10); 1944 if(e.keyCode == 13) { 1945 context.toggleDropdown.apply(context); 1946 return false;
1947 } 1948 }, 1949 onResizeWindow: function(e){ 1950 if(this.isActiveDrop()) { 1951 this.hideDropdown(); 1952 } 1953 }, 1954 onScrollWindow: function(e){ 1955 if(this.options.hideDropOnScroll) { 1956 this.hideDropdown(); 1957 } else if(this.isActiveDrop()) { 1958 this.positionDropdown(); 1959 } 1960 }, 1961 onOptionClick: function(e){ 1962 var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li'); 1963 if(opener) { 1964 this.dropOpened = true; 1965 this.realElement.selectedIndex = parseInt(opener.getAttribute('rel')); 1966 if(jcf.isTouchDevice) { 1967 this.onFocus(); 1968 } else { 1969 this.realElement.focus(); 1970 } 1971 this.refreshState(); 1972 this.hideDropdown(); 1973 jcf.lib.fireEvent(this.realElement, 'change'); 1974 } 1975 return false; 1976 }, 1977 onClickOutside: function(e){ 1978 if(jcf.tmpFlag) { 1979 jcf.tmpFlag = false; 1980 return; 1981 } 1982 if(!jcf.lib.isParent(this.fakeElement, e.target) && !jcf.lib.isParent(this.selectDrop, e.target)) { 1983 this.hideDropdown(); 1984 } 1985 }, 1986 onDropHover: function(e){ 1987 if(!this.keyboardFix) { 1988 this.hoverFlag = true; 1989 var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li'); 1990 if(opener) { 1991 this.realElement.selectedIndex = parseInt(opener.getAttribute('rel')); 1992 this.refreshSelectedClass(parseInt(opener.getAttribute('rel'))); 1993 } 1994 } else { 1995 this.keyboardFix = false; 1996 } 1997 }, 1998 onDropLeave: function(){ 1999 this.hoverFlag = false; 2000 }, 2001 isActiveDrop: function(){ 2002 return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass); 2003 }, 2004 isOverDrop: function(){ 2005 return this.hoverFlag; 2006 }, 2007 createDropdown: function(){ 2008 // remove old dropdown if exists 2009 if(this.selectDrop) { 2010 this.selectDrop.parentNode.removeChild(this.selectDrop); 2011 } 2012 2013 // create dropdown holder 2014 this.selectDrop = document.createElement('div'); 2015 this.selectDrop.className = this.options.dropClass; 2016 this.selectDrop.innerHTML = this.options.dropStructure; 2017 jcf.lib.setStyles(this.selectDrop, {position:'absolute'}); 2018 this.selectList = jcf.lib.queryBySelector(this.options.dropSelector,this.selectDrop)[0]; 2019 jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass); 2020 document.body.appendChild(this.selectDrop); 2021 this.selectDrop.jcf = this; 2022 jcf.lib.event.add(this.selectDrop, 'click', this.onOptionClick, this); 2023 jcf.lib.event.add(this.selectDrop, 'mouseover', this.onDropHover, this); 2024 jcf.lib.event.add(this.selectDrop, 'mouseout', this.onDropLeave, this); 2025 this.buildDropdown(); 2026 }, 2027 buildDropdown: function() { 2028 // build select options / optgroups 2029 this.buildDropdownOptions(); 2030 2031 // position and resize dropdown 2032 this.positionDropdown(); 2033 2034 // cut dropdown if height exceedes 2035 this.buildDropdownScroll(); 2036 }, 2037 buildDropdownOptions: function() { 2038 this.resStructure = ''; 2039 this.optNum = 0; 2040 for(var i = 0; i < this.realElement.children.length; i++) { 2041 this.resStructure += this.buildElement(this.realElement.children[i], i) +'\n'; 2042 } 2043 this.selectList.innerHTML = this.resStructure; 2044 }, 2045 buildDropdownScroll: function() { 2046 if(this.options.dropMaxHeight) { 2047 if(this.selectDrop.offsetHeight > this.options.dropMaxHeight) { 2048 this.selectList.style.height = this.options.dropMaxHeight+'px'; 2049 this.selectList.style.overflow = 'auto'; 2050 this.selectList.style.overflowX = 'hidden'; 2051 jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass); 2052 } 2053 } 2054 jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass)); 2055 }, 2056 parseOptionTitle: function(optTitle) { 2057 return (typeof optTitle === 'string' && /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i.test(optTitle)) ? optTitle : ''; 2058 }, 2059 buildElement: function(obj, index){ 2060 // build option 2061 var res = '', optImage; 2062 if(obj.tagName.toLowerCase() == 'option') { 2063 if(!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != 'option') { 2064 res += '<ul>'; 2065 } 2066 2067 optImage = this.parseOptionTitle(obj.title); 2068 res += '<li rel="'+(this.optNum++)+'" class="'+(obj.className? obj.className + ' ' : '')+(index % 2 ? 'option-even ' : '')+'jcfcalc"><a href="#">'+(optImage ? '<img src="'+optImage+'" alt="" />
2068' : '')+'<span>' + obj.innerHTML + '</span></a></li>'; 2069 if(!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != 'option') { 2070 res += '</ul>'; 2071 } 2072 return res; 2073 } 2074 // build option group with options 2075 else if(obj.tagName.toLowerCase() == 'optgroup' && obj.label) { 2076 res += '<div class="'+this.options.optGroupClass+'">'; 2077 res += '<strong class="jcfcalc"><em>'+(obj.label)+'</em></strong>'; 2078 for(var i = 0; i < obj.children.length; i++) { 2079 res += this.buildElement(obj.children[i], i); 2080 } 2081 res += '</div>'; 2082 return res; 2083 } 2084 }, 2085 positionDropdown: function(){ 2086 var ofs = jcf.lib.getOffset(this.fakeElement), selectAreaHeight = this.fakeElement.offsetHeight, selectDropHeight = this.selectDrop.offsetHeight; 2087 var fitInTop = ofs.top - selectDropHeight >= jcf.lib.getScrollTop() && jcf.lib.getScrollTop() + jcf.lib.getWindowHeight() < ofs.top + selectAreaHeight + selectDropHeight; 2088 2089 2090 if((this.options.handleDropPosition && fitInTop) || this.options.selectDropPosition === 'top') { 2091 this.selectDrop.style.top = (ofs.top - selectDropHeight)+'px'; 2092 jcf.lib.addClass(this.selectDrop, this.options.dropFlippedClass); 2093 } else { 2094 this.selectDrop.style.top = (ofs.top + selectAreaHeight)+'px'; 2095 jcf.lib.removeClass(this.selectDrop, this.options.dropFlippedClass); 2096 } 2097 this.selectDrop.style.left = ofs.left+'px'; 2098 this.selectDrop.style.width = this.fakeElement.offsetWidth+'px'; 2099 }, 2100 showDropdown: function(){ 2101 document.body.appendChild(this.selectDrop); 2102 jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass); 2103 jcf.lib.addClass(this.fakeElement,this.options.dropActiveClass); 2104 this.positionDropdown(); 2105 2106 // highlight current active item 2107 var activeItem = this.getFakeActiveOption(); 2108 this.removeClassFromItems(this.options.currentSelectedClass); 2109 jcf.lib.addClass(activeItem, this.options.currentSelectedClass); 2110 2111 // show current dropdown 2112 jcf.lib.event.add(window, 'resize', this.onResizeWindow, this); 2113 jcf.lib.event.add(window, 'scroll', this.onScrollWindow, this); 2114 jcf.lib.event.add(document, jcf.eventPress, this.onClickOutside, this); 2115 this.positionDropdown(); 2116 }, 2117 hideDropdown: function(partial){ 2118 if(this.selectDrop.parentNode) { 2119 if(this.selectDrop.offsetWidth) { 2120 this.selectDrop.parentNode.removeChild(this.selectDrop); 2121 } 2122 if(partial) { 2123 return; 2124 } 2125 } 2126 if(typeof this.origSelectedIndex === 'number') { 2127 this.realElement.selectedIndex = this.origSelectedIndex; 2128 } 2129 jcf.lib.removeClass(this.fakeElement,this.options.dropActiveClass); 2130 jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass); 2131 jcf.lib.event.remove(window, 'resize', this.onResizeWindow); 2132 jcf.lib.event.remove(window, 'scroll', this.onScrollWindow); 2133 jcf.lib.event.remove(document.documentElement, jcf.eventPress, this.onClickOutside); 2134 if(jcf.isTouchDevice) { 2135 this.onBlur(); 2136 } 2137 }, 2138 toggleDropdown: function(){ 2139 if(!this.realElement.disabled) { 2140 if(jcf.isTouchDevice) { 2141 this.onFocus(); 2142 } else { 2143 this.realElement.focus(); 2144 } 2145 if(this.isActiveDrop()) { 2146 this.hideDropdown(); 2147 } else { 2148 this.showDropdown(); 2149 } 2150 this.refreshState(); 2151 } 2152 }, 2153 scrollToItem: function(){ 2154 if(this.isActiveDrop()) { 2155 var dropHeight = this.selectList.offsetHeight; 2156 var offsetTop = this.calcOptionOffset(this.getFakeActiveOption()); 2157 var sTop = this.selectList.scrollTop; 2158 var oHeight = this.getFakeActiveOption().offsetHeight; 2159 //offsetTop+=sTop; 2160 2161 if(offsetTop >= sTop + dropHeight) { 2162 this.selectList.scrollTop = offsetTop - dropHeight + oHeight; 2163 } else if(offsetTop < sTop) { 2164 this.selectList.scrollTop = offsetTop; 2165 } 2166 } 2167 }, 2168 getFakeActiveOption: function(c) { 2169 return jcf.lib.queryBySelector('li[rel="'+(typeof c === 'number' ? c : this.realElement.selectedIndex) +'"]',this.selectList)[0]; 2170 }, 2171 calcOptionOffset: function(fake) { 2172 var h = 0;
2173 var els = jcf.lib.queryBySelector('.jcfcalc',this.selectList); 2174 for(var i = 0; i < els.length; i++) { 2175 if(els[i] == fake) break; 2176 h+=els[i].offsetHeight; 2177 } 2178 return h; 2179 }, 2180 childrenHasItem: function(hold,item) { 2181 var items = hold.getElementsByTagName('*'); 2182 for(i = 0; i < items.length; i++) { 2183 if(items[i] == item) return true; 2184 } 2185 return false; 2186 }, 2187 removeClassFromItems: function(className){ 2188 var children = jcf.lib.queryBySelector('li',this.selectList); 2189 for(var i = children.length - 1; i >= 0; i--) { 2190 jcf.lib.removeClass(children[i], className); 2191 } 2192 }, 2193 setSelectedClass: function(c){ 2194 jcf.lib.addClass(this.getFakeActiveOption(c), this.options.selectedClass); 2195 }, 2196 refreshSelectedClass: function(c){ 2197 if(!this.options.showNativeDrop) { 2198 this.removeClassFromItems(this.options.selectedClass); 2199 this.setSelectedClass(c); 2200 } 2201 if(this.realElement.disabled) { 2202 jcf.lib.addClass(this.fakeElement, this.options.disabledClass); 2203 if(this.labelFor) { 2204 jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass); 2205 } 2206 } else { 2207 jcf.lib.removeClass(this.fakeElement, this.options.disabledClass); 2208 if(this.labelFor) { 2209 jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass); 2210 } 2211 } 2212 }, 2213 refreshSelectedText: function() { 2214 if(!this.dropOpened && this.realElement.title) { 2215 this.valueText.innerHTML = this.realElement.title; 2216 } else { 2217 if(this.realElement.options[this.realElement.selectedIndex].title) { 2218 var optImage = this.parseOptionTitle(this.realElement.options[this.realElement.selectedIndex].title); 2219 this.valueText.innerHTML = (optImage ? '<img src="'+optImage+'" alt="" />' : '') + this.realElement.options[this.realElement.selectedIndex].innerHTML; 2220 } else { 2221 this.valueText.innerHTML = this.realElement.options[this.realElement.selectedIndex].innerHTML; 2222 } 2223 } 2224 }, 2225 refreshState: function(){ 2226 this.origSelectedIndex = this.realElement.selectedIndex; 2227 this.refreshSelectedClass(); 2228 this.refreshSelectedText(); 2229 if(!this.options.showNativeDrop) { 2230 this.positionDropdown(); 2231 if(this.selectDrop.offsetWidth) { 2232 this.scrollToItem(); 2233 } 2234 } 2235 } 2236}); 2237 2238// custom radio module 2239jcf.addModule({ 2240 name:'radio', 2241 selector: 'input[type="radio"]', 2242 defaultOptions: { 2243 wrapperClass:'rad-area', 2244 focusClass:'rad-focus', 2245 checkedClass:'rad-checked', 2246 uncheckedClass:'rad-unchecked', 2247 disabledClass:'rad-disabled', 2248 radStructure:'<span></span>' 2249 }, 2250 getRadioGroup: function(item){ 2251 var name = item.getAttribute('name'); 2252 if(name) { 2253 return jcf.lib.queryBySelector('input[name="'+name+'"]', jcf.lib.getParent('form')); 2254 } else { 2255 return [item]; 2256 } 2257 }, 2258 setupWrapper: function(){ 2259 jcf.lib.addClass(this.fakeElement, this.options.wrapperClass); 2260 this.fakeElement.innerHTML = this.options.radStructure; 2261 this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement); 2262 this.refreshState(); 2263 this.addEvents(); 2264 }, 2265 addEvents: function(){ 2266 jcf.lib.event.add(this.fakeElement, 'click', this.toggleRadio, this); 2267 if(this.labelFor) { 2268 jcf.lib.event.add(this.labelFor, 'click', this.toggleRadio, this); 2269 } 2270 }, 2271 onFocus: function(e) { 2272 jcf.modules[this.name].superclass.onFocus.apply(this, arguments); 2273 setTimeout(jcf.lib.bind(function(){ 2274 this.refreshState(); 2275 },this),10); 2276 }, 2277 toggleRadio: function(){ 2278 if(!this.realElement.disabled) { 2279 this.realElement.checked = true; 2280 } 2281 this.refreshState(); 2282 //alert('toggle radio ' + this.realElement.id) ; 2283 if ( this.realElement.onchange) { 2284 this.realElement.onchange() ; 2285 } 2286 }, 2287 refreshState: function(){ 2288 var els = this.getRadioGroup(this.realElement); 2289 for(var i = 0; i < els.length; i++) { 2290 var curEl = els[i].jcf; 2291 if(curEl) { 2292 if(curEl.realElement.checked) { 2293 jcf.lib.addClass(curEl.fakeElement, curEl.options.checkedClass); 2294 jcf.lib.removeClass(curEl.fakeElement, curEl.options.uncheckedClass); 2295 if(curEl.labelFor) { 2296 jcf.lib.addClass(curEl.labelFor, curEl.options.labelActiveClass); 2297 } 2298 } else { 2299 jcf.lib.removeClass(curEl.fakeElement, curEl.options.checkedClass); 2300 jcf.lib.addClass(curEl.fakeElement, curEl.options.uncheckedClass); 2301 if(curEl.labelFor) { 2302 jcf.lib.removeClass(curEl.labelFor, curEl.options.labelActiveClass); 2303 } 2304 } 2305 if(curEl.realElement.disabled) { 2306 jcf.lib.addClass(curEl.fakeElement, curEl.options.disabledClass); 2307 if(curEl.labelFor) { 2308 jcf.lib.addClass(curEl.labelFor, curEl.options.labelDisabledClass); 2309 } 2310 } else { 2311 jcf.lib.removeClass(curEl.fakeElement, curEl.options.disabledClass); 2312 if(curEl.labelFor) { 2313 jcf.lib.removeClass(curEl.labelFor, curEl.options.labelDisabledClass); 2314 } 2315 } 2316 } 2317 } 2318 } 2319}); 2320 2321// custom upload field module 2322var the_nav = navigator.userAgent.toString().toLowerCase() ; 2323if (the_nav.indexOf('firefox') == -1) { 2324 jcf.addModule( { 2325 name: 'file', 2326 selector: 'input[type="file"]', 2327 defaultOptions: { 2328 buttonWidth: 30, 2329 bigFontSize: 200, 2330 buttonText:'Parcourir', 2331 wrapperClass:'file-area', 2332 focusClass:'file-focus', 2333 disabledClass:'file-disabled', 2334 opacityClass:'file-input-opacity', 2335 noFileClass:'no-file', 2336 extPrefixClass:'extension-', 2337 uploadStructure:'<div class="jcf-input-wrapper"><div class="jcf-wrap"></div><label class="jcf-fake-input"><span><em></em></span></label><a class="jcf-upload-button"><span></span></a></div>', 2338 uploadFileNameSelector:'label.jcf-fake-input span em', 2339 uploadButtonSelector:'a.jcf-upload-button span', 2340 inputWrapper: 'div.jcf-wrap' 2341 }, 2342 setupWrapper: function(){ 2343 jcf.lib.addClass(this.fakeElement, this.options.wrapperClass); 2344 this.fakeElement.innerHTML = this.options.uploadStructure; 2345 this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement); 2346 this.fileNameInput = jcf.lib.queryBySelector(this.options.uploadFileNameSelector ,this.fakeElement)[0]; 2347 this.uploadButton = jcf.lib.queryBySelector(this.options.uploadButtonSelector ,this.fakeElement)[0]; 2348 this.inputWrapper = jcf.lib.queryBySelector(this.options.inputWrapper ,this.fakeElement)[0]; 2349 2350 this.origTitle = this.realElement.title; 2351 this.fileNameInput.innerHTML = this.realElement.title || ''; 2352 this.uploadButton.innerHTML = this.options.buttonText; 2353 this.realElement.removeAttribute('title'); 2354 this.fakeElement.style.position = 'relative'; 2355 this.realElement.style.position = 'absolute'; 2356 this.realElement.style.zIndex = 100; 2357 this.inputWrapper.appendChild(this.realElement); 2358 this.oTop = this.oLeft = this.oWidth = this.oHeight = 0; 2359 2360 jcf.lib.addClass(this.realElement, this.options.opacityClass); 2361 jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass); 2362 this.inputWrapper.style.width = this.inputWrapper.parentNode.offsetWidth+'px'; 2363 2364 this.shakeInput(); 2365 this.refreshState(); 2366 this.addEvents(); 2367 }, 2368 addEvents: function(){ 2369 jcf.lib.event.add(this.realElement, 'change', this.onChange, this); 2370 if(!jcf.isTouchDevice) { 2371 jcf.lib.event.add(this.fakeElement, 'mousemove', this.onMouseMove, this); 2372 jcf.lib.event.add(this.fakeElement, 'mouseover', this.recalcDimensions, this); 2373 } 2374 }, 2375 onMouseMove: function(e){ 2376 this.realElement.style.top = Math.round(e.pageY - this.oTop - this.oHeight/2) + 'px'; 2377 this.realElement.style.left = (e.pageX - this.oLeft - this.oWidth + this.options.buttonWidth) + 'px'; 2378 }, 2379 onChange: function(){ 2380 this.refreshState(); 2381 }, 2382 getFileName: function(){ 2383 return this.realElement.value.replace(/^[\s\S]*(?:\\|\/)([\s\S^\\\/]*)$/g, "$1"); 2384 }, 2385 getFileExtension: function(){ 2386 return this.realElement.value.lastIndexOf('.') < 0 ? false : this.realElement.value.substring(this.realElement.value.lastIndexOf('.')+1).toLowerCase(); 2387 }, 2388 updateExtensionClass: function(){ 2389 var currentExtension = this.getFileExtension(); 2390 if(currentExtension) { 2391 this.fakeElement.className = this.fakeElement.className.replace(new RegExp('(\\s|^)'+this.options.extPrefixClass+'[^ ]+','gi'),'') 2392 jcf.lib.addClass(this.fakeElement, this.options.extPrefixClass+currentExtension) 2393 } 2394 }, 2395 shakeInput: function() { 2396 // make input bigger 2397 jcf.lib.setStyles(this.realElement, { 2398 fontSize: this.options.bigFontSize, 2399 lineHeight: this.options.bigFontSize, 2400 heigth: 'auto', 2401 top: 0, 2402 left: this.inputWrapper.offsetWidth - this.realElement.offsetWidth 2403 }); 2404 // IE styling fix 2405 if((/(MSIE)/gi).test(navigator.userAgent)) { 2406 this.tmpElement = document.createElement('span'); 2407 this.inputWrapper.insertBefore(this.tmpElement,this.realElement); 2408 this.inputWrapper.insertBefore(this.realElement,this.tmpElement); 2409 this.inputWrapper.removeChild(this.tmpElement); 2410 } 2411 }, 2412 recalcDimensions: function() { 2413 var o = jcf.lib.getOffset(this.fakeElement); 2414 this.oTop = o.top; 2415 this.oLeft = o.left; 2416 this.oWidth = this.realElement.offsetWidth; 2417 this.oHeight = this.realElement.offsetHeight; 2418 }, 2419 refreshState: function(){ 2420 jcf.lib.setStyles(this.realElement, {opacity: 0}); 2421 this.fileNameInput.innerHTML = this.getFileName() || this.origTitle || ''; 2422 if(this.realElement.disabled) { 2423 jcf.lib.addClass(this.fakeElement, this.options.disabledClass); 2424 if(this.labelFor) { 2425 jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass); 2426 } 2427 } else { 2428 jcf.lib.removeClass(this.fakeElement, this.options.disabledClass); 2429 if(this.labelFor) { 2430 jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass); 2431 } 2432 } 2433 if(this.realElement.value.length) { 2434 jcf.lib.removeClass(this.fakeElement, this.options.noFileClass); 2435 } else { 2436 jcf.lib.addClass(this.fakeElement, this.options.noFileClass); 2437 } 2438 this.updateExtensionClass(); 2439 } 2440 }); 2441} 2442 2443 2444// placeholder class 2445 2446;(function(){ 2447 var placeholderCollection = []; 2448 PlaceholderInput = function() { 2449 this.options = { 2450 element:null, 2451 showUntilTyping:false, 2452 wrapWithElement:false, 2453 getParentByClass:false, 2454 showPasswordBullets:false, 2455 placeholderAttr:'value', 2456 inputFocusClass:'focus', 2457 inputActiveClass:'text-active', 2458 parentFocusClass:'parent-focus', 2459 parentActiveClass:'parent-active', 2460 labelFocusClass:'label-focus', 2461 labelActiveClass:'label-active', 2462 fakeElementClass:'input-placeholder-text' 2463 }; 2464 placeholderCollection.push(this); 2465 this.init.apply(this,arguments); 2466 }; 2467 PlaceholderInput.refreshAllInputs = function(except) { 2468 for(var i = 0; i < placeholderCollection.length; i++) { 2469 if(except !== placeholderCollection[i]) { 2470 placeholderCollection[i].refreshState(); 2471 } 2472 } 2473 }; 2474 PlaceholderInput.replaceByOptions = function(opt) { 2475 var inputs = [].concat( 2476 convertToArray(document.getElementsByTagName('input')), 2477 convertToArray(document.getElementsByTagName('textarea')) 2478 ); 2479 for(var i = 0; i < inputs.length; i++) { 2480 var inputID = inputs[i].id ; 2481 if (inputID == "mini_cv") { continue ;} 2482 if (inputID == "forum_subject") { continue ;} 2483 if (inputID == "message-1") { continue ;} 2484 if (inputID == "message-2") { continue ;} 2485 if(inputs[i].className.indexOf(opt.skipClass) < 0) 2486 { 2487 var inputType = getInputType(inputs[i]); 2488 var placeholderValue = inputs[i].getAttribute('placeholder'); 2489 if(opt.focusOnly || (opt.clearInputs && (inputType === 'text' || inputType === 'email' || placeholderValue)) || 2490 (opt.clearTextareas && inputType === 'textarea') || 2491 (opt.clearPasswords && inputType === 'password') 2492 ) { 2493 new PlaceholderInput({ 2494 element:inputs[i], 2495 focusOnly: opt.focusOnly, 2496 wrapWithElement:opt.wrapWithElement, 2497 showUntilTyping:opt.showUntilTyping, 2498 getParentByClass:opt.getParentByClass, 2499 showPasswordBullets:opt.showPasswordBullets, 2500 placeholderAttr: placeholderValue ? 'placeholder' : opt.placeholderAttr 2501 }); 2502 } 2503 } 2504 } 2505 }; 2506 PlaceholderInput.prototype = { 2507 init: function(opt) { 2508 this.setOptions(opt); 2509 if(this.element && this.element.PlaceholderInst) { 2510 this.element.PlaceholderInst.refreshClasses(); 2511 } else { 2512 this.element.PlaceholderInst = this; 2513 if(this.elementType !== 'radio' || this.elementType !== 'checkbox' || this.elementType !== 'file') { 2514 this.initElements(); 2515 this.attachEvents(); 2516 this.refreshClasses(); 2517 } 2518 } 2519 }, 2520 setOptions: function(opt) { 2521 for(var p in opt) { 2522 if(opt.hasOwnProperty(p)) { 2523 this.options[p] = opt[p]; 2524 } 2525 } 2526 if(this.options.element) { 2527 this.element = this.options.element; 2528 this.elementType = getInputType(this.element); 2529 if(this.options.focusOnly) { 2530 this.wrapWithElement = false;
2531 } else { 2532 if(this.elementType === 'password' && this.options.showPasswordBullets) { 2533 this.wrapWithElement = false; 2534 } else { 2535 this.wrapWithElement = this.elementType === 'password' || this.options.showUntilTyping ? true : this.options.wrapWithElement; 2536 } 2537 } 2538 this.setPlaceholderValue(this.options.placeholderAttr); 2539 } 2540 }, 2541 setPlaceholderValue: function(attr) { 2542 this.origValue = (attr === 'value' ? this.element.defaultValue : (this.element.getAttribute(attr) || '')); 2543 if(this.options.placeholderAttr !== 'value') { 2544 this.element.removeAttribute(this.options.placeholderAttr); 2545 } 2546 }, 2547 initElements: function() { 2548 // create fake element if needed 2549 if(this.wrapWithElement) { 2550 this.fakeElement = document.createElement('span'); 2551 this.fakeElement.className = this.options.fakeElementClass; 2552 this.fakeElement.innerHTML += this.origValue; 2553 this.fakeElement.style.color = getStyle(this.element, 'color'); 2554 this.fakeElement.style.position = 'absolute'; 2555 this.element.parentNode.insertBefore(this.fakeElement, this.element); 2556 2557 if(this.element.value === this.origValue || !this.element.value) { 2558 this.element.value = ''; 2559 this.togglePlaceholderText(true); 2560 } else { 2561 this.togglePlaceholderText(false); 2562 } 2563 } else if(!this.element.value && this.origValue.length) { 2564 this.element.value = this.origValue; 2565 } 2566 // get input label 2567 if(this.element.id) { 2568 this.labels = document.getElementsByTagName('label'); 2569 for(var i = 0; i < this.labels.length; i++) { 2570 if(this.labels[i].htmlFor === this.element.id) { 2571 this.labelFor = this.labels[i]; 2572 break; 2573 } 2574 } 2575 } 2576 // get parent node (or parentNode by className) 2577 this.elementParent = this.element.parentNode; 2578 if(typeof this.options.getParentByClass === 'string') { 2579 var el = this.element; 2580 while(el.parentNode) { 2581 if(hasClass(el.parentNode, this.options.getParentByClass)) { 2582 this.elementParent = el.parentNode; 2583 break; 2584 } else { 2585 el = el.parentNode; 2586 } 2587 } 2588 } 2589 }, 2590 attachEvents: function() { 2591 this.element.onfocus = bindScope(this.focusHandler, this); 2592 this.element.onblur = bindScope(this.blurHandler, this); 2593 if(this.options.showUntilTyping) { 2594 this.element.onkeydown = bindScope(this.typingHandler, this); 2595 this.element.onpaste = bindScope(this.typingHandler, this); 2596 } 2597 if(this.wrapWithElement) this.fakeElement.onclick = bindScope(this.focusSetter, this); 2598 }, 2599 togglePlaceholderText: function(state) { 2600 if(!this.element.readOnly && !this.options.focusOnly) { 2601 if(this.wrapWithElement) { 2602 this.fakeElement.style.display = state ? '' : 'none'; 2603 } else { 2604 this.element.value = state ? this.origValue : ''; 2605 } 2606 } 2607 }, 2608 focusSetter: function() { 2609 this.element.focus(); 2610 }, 2611 focusHandler: function() { 2612 clearInterval(this.checkerInterval); 2613 this.checkerInterval = setInterval(bindScope(this.intervalHandler,this), 1); 2614 this.focused = true; 2615 if(!this.element.value.length || this.element.value === this.origValue) { 2616 if(!this.options.showUntilTyping) { 2617 this.togglePlaceholderText(false); 2618 } 2619 } 2620 this.refreshClasses(); 2621 }, 2622 blurHandler: function() { 2623 clearInterval(this.checkerInterval); 2624 this.focused = false; 2625 if(!this.element.value.length || this.element.value === this.origValue) { 2626 this.togglePlaceholderText(true); 2627 } 2628 this.refreshClasses(); 2629 PlaceholderInput.refreshAllInputs(this); 2630 }, 2631 typingHandler: function() { 2632 setTimeout(bindScope(function(){ 2633 if(this.element.value.length) { 2634 this.togglePlaceholderText(false); 2635 this.refreshClasses(); 2636 } 2637 },this), 10); 2638 }, 2639 intervalHandler: function() { 2640 if(typeof this.tmpValue === 'undefined') { 2641 this.tmpValue = this.element.value; 2642 } 2643 if(this.tmpValue != this.element.value) { 2644 PlaceholderInput.refreshAllInputs(this); 2645 } 2646 }, 2647 refreshState: function() { 2648 if(this.wrapWithElement) { 2649 if(this.element.value.length && this.element.value !== this.origValue) { 2650 this.togglePlaceholderText(false); 2651 } else if(!this.element.value.length) { 2652 this.togglePlaceholderText(true); 2653 } 2654 } 2655 this.refreshClasses(); 2656 }, 2657 refreshClasses: function() { 2658 this.textActive = this.focused || (this.element.value.length && this.element.value !== this.origValue); 2659 this.setStateClass(this.element, this.options.inputFocusClass,this.focused); 2660 this.setStateClass(this.elementParent, this.options.parentFocusClass,this.focused); 2661 this.setStateClass(this.labelFor, this.options.labelFocusClass,this.focused); 2662 this.setStateClass(this.element, this.options.inputActiveClass, this.textActive); 2663 this.setStateClass(this.elementParent, this.options.parentActiveClass, this.textActive); 2664 this.setStateClass(this.labelFor, this.options.labelActiveClass, this.textActive); 2665 }, 2666 setStateClass: function(el,cls,state) { 2667 if(!el) return; else if(state) addClass(el,cls); else removeClass(el,cls); 2668 } 2669 }; 2670 2671 // utility functions 2672 function convertToArray(collection) { 2673 var arr = []; 2674 for (var i = 0, ref = arr.length = collection.length; i < ref; i++) { 2675 arr[i] = collection[i]; 2676 } 2677 return arr; 2678 } 2679 function getInputType(input) { 2680 return (input.type ? input.type : input.tagName).toLowerCase(); 2681 } 2682 function hasClass(el,cls) { 2683 return el.className ? el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')) : false;
2684 } 2685 function addClass(el,cls) { 2686 if (!hasClass(el,cls)) el.className += " "+cls; 2687 } 2688 function removeClass(el,cls) { 2689 if (hasClass(el,cls)) {el.className=el.className.replace(new RegExp('(\\s|^)'+cls+'(\\s|$)'),' ');} 2690 } 2691 function bindScope(f, scope) { 2692 return function() {return f.apply(scope, arguments);}; 2693 } 2694 function getStyle(el, prop) { 2695 if (document.defaultView && document.defaultView.getComputedStyle) { 2696 return document.defaultView.getComputedStyle(el, null)[prop]; 2697 } else if (el.currentStyle) { 2698 return el.currentStyle[prop]; 2699 } else { 2700 return el.style[prop]; 2701 } 2702 } 2703}()); 2704 2705 2706/* 2707* touchSwipe - jQuery Plugin 2708* https://github.com/mattbryson/TouchSwipe-Jquery-Plugin 2709* http://labs.skinkers.com/touchSwipe/ 2710* http://plugins.jquery.com/project/touchSwipe 2711* 2712* Copyright (c) 2010 Matt Bryson (www.skinkers.com) 2713* Dual licensed under the MIT or GPL Version 2 licenses. 2714* 2715* $version: 1.5.1 2716*/ 2717 2718/*;(function(d){var l="left",k="right",c="up",r="down",b="in",s="out",i="none",o="auto",u="horizontal",p="vertical",f="all",e="start",h="move",g="end",m="cancel",a="ontouchstart" in window,t="TouchSwipe";var j={fingers:1,threshold:75,maxTimeThreshold:null,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,triggerOnTouchEnd:true,allowPageScroll:"auto",fallbackToMouseEvents:true,excludedElements:"button, input, select, textarea, a, .noSwipe"};d.fn.swipe=function(x){var w=d(this),v=w.data(t);if(v&&typeof x==="string"){if(v[x]){return v[x].apply(this,Array.prototype.slice.call(arguments,1))}else{d.error("Method "+x+" does not exist on jQuery.swipe")}}else{if(!v&&(typeof x==="object"||!x)){return q.apply(this,arguments)}}return w};d.fn.swipe.defaults=j;d.fn.swipe.phases={PHASE_START:e,PHASE_MOVE:h,PHASE_END:g,PHASE_CANCEL:m};d.fn.swipe.directions={LEFT:l,RIGHT:k,UP:c,DOWN:r,IN:b,OUT:s};d.fn.swipe.pageScroll={NONE:i,HORIZONTAL:u,VERTICAL:p,AUTO:o};d.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:f};function q(v){if(v&&(v.allowPageScroll===undefined&&(v.swipe!==undefined||v.swipeStatus!==undefined))){v.allowPageScroll=i}if(!v){v={}}v=d.extend({},d.fn.swipe.defaults,v);return this.each(function(){var x=d(this);var w=x.data(t);if(!w){w=new n(this,v);x.data(t,w)}})}function n(J,R){var aj=(a||!R.fallbackToMouseEvents),ae=aj?"touchstart":"mousedown",K=aj?"touchmove":"mousemove",ac=aj?"touchend":"mouseup",I="touchcancel";var P=0;var E=null;var S=0;var af=0;var w=0;var U=1;var ak=0;var A=d(J);var F="start";var ai=0;var T=null;var B=0;var M=0;try{A.bind(ae,aa);A.bind(I,D)}catch(ag){d.error("events not supported "+ae+","+I+" on jQuery.swipe")}this.enable=function(){A.bind(ae,aa);A.bind(I,D);return A};this.disable=function(){H();return A};this.destroy=function(){H();A.data(t,null);return A};function aa(ao){if(L()){return}if(d(ao.target).closest(R.excludedElements,A).length>0){return}ao=ao.originalEvent;var an,am=a?ao.touches[0]:ao;F=e;if(a){ai=ao.touches.length}else{ao.preventDefault()}P=0;E=null;ak=null;S=0;af=0;w=0;U=1;T=al();if(!a||(ai===R.fingers||R.fingers===f)||W()){T[0].start.x=T[0].end.x=am.pageX;T[0].start.y=T[0].end.y=am.pageY;B=x();if(ai==2){T[1].start.x=T[1].end.x=ao.touches[1].pageX;T[1].start.y=T[1].end.y=ao.touches[1].pageY;af=w=N(T[0].start,T[1].start)}if(R.swipeStatus||R.pinchStatus){an=ah(ao,F)}}else{D(ao);an=false}if(an===false){F=m;ah(ao,F);return an}else{V(true);A.bind(K,G);A.bind(ac,O)}}function G(ap){ap=ap.originalEvent;if(F===g||F===m){return}var an,am=a?ap.touches[0]:ap;T[0].end.x=a?ap.touches[0].pageX:am.pageX;T[0].end.y=a?ap.touches[0].pageY:am.pageY;M=x();E=Z(T[0].start,T[0].end);if(a){ai=ap.touches.length}F=h;if(ai==2){if(af==0){T[1].start.x=ap.touches[1].pageX;T[1].start.y=ap.touches[1].pageY;af=w=N(T[0].start,T[1].start)}else{T[1].end.x=ap.touches[1].pageX;T[1].end.y=ap.touches[1].pageY;w=N(T[0].end,T[1].end);ak=X(T[0].end,T[1].end)}U=v(af,w)}if((ai===R.fingers||R.fingers===f)||!a){y(ap,E);P=z(T[0].start,T[0].end);S=C(T[0].start,T[0].end);if(R.swipeStatus||R.pinchStatus){an=ah(ap,F)}if(!R.triggerOnTouchEnd){var ao=!Y();if(Q()===true){F=g;an=ah(ap,F)}else{if(ao){F=m;ah(ap,F)}}}}else{F=m;ah(ap,F)}if(an===false){F=m;ah(ap,F)}}function O(at){at=at.originalEvent;if(at.touches&&at.touches.length>0){return true}at.preventDefault();M=x();if(af!=0){w=N(T[0].end,T[1].end);U=v(af,w);ak=X(T[0].end,T[1].end)}P=z(T[0].start,T[0].end);E=Z(T[0].start,T[0].end);S=C();if(R.triggerOnTouchEnd||(R.triggerOnTouchEnd===false&&F===h)){F=g;var ap=ad()||!W();var an=((ai===R.fingers||R.fingers===f)||!a);var am=T[0].end.x!==0;var ao=(an&&am&&ap);if(ao){var aq=Y();var ar=Q();if((ar===true||ar===null)&&aq){ah(at,F)}else{if(!aq||ar===false){F=m;ah(at,F)}}}else{F=m;ah(at,F)}}else{if(F===h){F=m;ah(at,F)}}A.unbind(K,G,false);A.unbind(ac,O,false);V(false)}function D(){ai=0;M=0;B=0;af=0;w=0;U=1;V(false)}function ah(ao,am){var an=undefined;if(R.swipeStatus){an=R.swipeStatus.call(A,ao,am,E||null,P||0,S||0,ai)}if(R.pinchStatus&&ad()){an=R.pinchStatus.call(A,ao,am,ak||null,w||0,S||0,ai,U)}if(am===m){if(R.click&&(ai===1||!a)&&(isNaN(P)||P===0)){an=R.click.call(A,ao,ao.target)}}if(am==g){if(R.swipe){an=R.swipe.call(A,ao,E,P,S,ai)}switch(E){case l:if(R.swipeLeft){an=R.swipeLeft.call(A,ao,E,P,S,ai)}break;case k:if(R.swipeRight){an=R.swipeRight.call(A,ao,E,P,S,ai)}break;case c:if(R.swipeUp){an=R.swipeUp.call(A,ao,E,P,S,ai)}break;case r:if(R.swipeDown){an=R.swipeDown.call(A,ao,E,P,S,ai)}break}switch(ak){case b:if(R.pinchIn){an=R.pinchIn.call(A,ao,ak||null,w||0,S||0,ai,U)}break;case s:if(R.pinchOut){an=R.pinchOut.call(A,ao,ak||null,w||0,S||0,ai,U)}break}}if(am===m||am===g){D(ao)}return an}function Q(){if(R.threshold!==null){return P>=R.threshold}return null}function Y(){var am;if(R.maxTimeThreshold){if(S>=R.maxTimeThreshold){am=false}else{am=true}}else{am=true}return am}function y(am,an){if(R.allowPageScroll===i||W()){am.preventDefault()}else{var ao=R.allowPageScroll===o;switch(an){case l:if((R.swipeLeft&&ao)||(!ao&&R.allowPageScroll!=u)){am.preventDefault()}break;case k:if((R.swipeRight&&ao)||(!ao&&R.allowPageScroll!=u)){am.preventDefault()}break;
2718case c:if((R.swipeUp&&ao)||(!ao&&R.allowPageScroll!=p)){am.preventDefault()}break;case r:if((R.swipeDown&&ao)||(!ao&&R.allowPageScroll!=p)){am.preventDefault()}break}}}function C(){return M-B}function N(ap,ao){var an=Math.abs(ap.x-ao.x);var am=Math.abs(ap.y-ao.y);return Math.round(Math.sqrt(an*an+am*am))}function v(am,an){var ao=(an/am)*1;return ao.toFixed(2)}function X(){if(U<1){return s}else{return b}}function z(an,am){return Math.round(Math.sqrt(Math.pow(am.x-an.x,2)+Math.pow(am.y-an.y,2)))}function ab(ap,an){var am=ap.x-an.x;var ar=an.y-ap.y;var ao=Math.atan2(ar,am);var aq=Math.round(ao*180/Math.PI);if(aq<0){aq=360-Math.abs(aq)}return aq}function Z(an,am){var ao=ab(an,am);if((ao<=45)&&(ao>=0)){return l}else{if((ao<=360)&&(ao>=315)){return l}else{if((ao>=135)&&(ao<=225)){return k}else{if((ao>45)&&(ao<135)){return r}else{return c}}}}}function x(){var am=new Date();return am.getTime()}function H(){A.unbind(ae,aa);A.unbind(I,D);A.unbind(K,G);A.unbind(ac,O);V(false)}function W(){return R.pinchStatus||R.pinchIn||R.pinchOut}function ad(){return ak&&W()}function L(){return A.data(t+"_intouch")===true?true:false}function V(am){am=am===true?true:false;A.data(t+"_intouch",am)}function al(){var am=[];for(var an=0;an<=5;an++){am.push({start:{x:0,y:0},end:{x:0,y:0},delta:{x:0,y:0}})}return am}}})(jQuery); 2719*/
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.