1// page init 2 3jQuery(function(){ 4 5 initTabs(); 6 7 if( (location.pathname != "/magazine-subscription") && (location.pathname != "/renew-subscriptions") ) 8 { 9 jcf.customForms.replaceAll(); 10 } 11 12 initCarousel(); 13 14 initAccordion(); 15 16 initSameHeight(); 17 18 initFitVids(); 19 20 //initDateRange(); 21 22 advance_search(); 23 24 addAnchorImage(); 25 26 fancy_box(); 27 28 jQuery('input, textarea').placeholder(); 29 30 device(); 31 32 jQuery('#homead5').mouseover(function() 33 { 34 jQuery(this).css('overflow','inherit') 35 } 36 ); 37 38}); 39jQuery(window).scroll(function(){ 40 41if (jQuery(window).scrollTop() + jQuery(window).height() > jQuery('#footer').position().top-100){ 42jQuery("#main.hmoe,#main.ros").css("background-attachment","inherit"); 43jQuery("#main.hmoe,#main.ros").css("background-position-y","-691px").css("scroll-behavior","smooth"); 44jQuery("#main.hmoe,#main.ros").css("background-position","bottom"); 45} 46else{ 47jQuery("#main.hmoe,#main.ros").css("background-attachment","fixed"); 48jQuery("#main.hmoe,#main.ros").css("background-position","top"); 49jQuery("#main.hmoe,#main.ros").css("background-position-y","65px").css("scroll-behavior","smooth"); 50} 51 52}); 53function openFile(file) { 54 55 56 57 if(typeof file ==='undefined' || file == null) 58 59 { 60 61 return false; 62 63 } 64 65 var extension = file.substr( (file.lastIndexOf('.') +1) ); 66 67 switch(extension.toLowerCase()) { 68 69 case 'jpg': 70 71 case 'png': 72 73 case 'gif': 74 75 return true; // There's was a typo in the example where 76 77 break; 78 79 default: 80 81 return false; 82 83 } 84 85}; 86 87function device(){ 88 89 var isMobile = false; //initiate as false 90 91// device detection 92 93if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 94 95 || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.
95substr(0,4))) isMobile = true; 96 97 98 99if(isMobile == false) { 100 101 isMobiles(); 102 103 104 105} 106 107 108 109} 110 111var sticky; 112window.onload = (event) => { 113 sticky = header.offsetTop; 114} 115window.onscroll = function() {stickyTakeOver()}; 116 117var header = document.getElementById("navblock"); 118 119 120function stickyTakeOver() { 121 if (window.pageYOffset > sticky) { 122 header.classList.add("sticky"); 123 } else { 124 header.classList.remove("sticky"); 125 } 126} 127 128function isMobiles(){ 129 130 // Create a clone of the menu, right next to original. 131 132jQuery('.navigation-block').addClass('original').clone().insertAfter('.navigation-block').addClass('cloned').css('position','fixed').css('top','0').css('margin-top','0').css('z-index','1000000').removeClass('original').hide(); 133 134//stickIt=stickIt(); 135 136scrollIntervalID = setInterval(stickIt, 10); 137 138 139 140 141 142function stickIt() { 143 144 145 146 var orgElementPos = jQuery('.original').offset(); 147 148 orgElementTop = orgElementPos.top; 149 150 151 152 if (jQuery(window).scrollTop() >= (orgElementTop)) { 153 154 // scrolled past the original position; now only show the cloned, sticky element. 155 156 157 158 // Cloned element should always have same left position and width as original element. 159 160 orgElement = jQuery('.original'); 161 162 coordsOrgElement = orgElement.offset(); 163 164 leftOrgElement = coordsOrgElement.left; 165 166 widthOrgElement = orgElement.css('width'); 167 168 jQuery('.cloned').css('left',leftOrgElement+'px').css('top',0).css('width',widthOrgElement).show(); 169 170 jQuery('.original').css('visibility','hidden'); 171 172 jQuery('.original').css('overflow','hidden'); 173 174 } 175 /* sticky view */ 176 else if(jQuery(window).scrollTop() == 0){ 177 //confirm("yes"); 178 jQuery("#main.hmoe, .hmoe .left_grip,#main.ros, .ros .left_grip").css("background-position-y",jQuery('#header').height()).css("scroll-behavior","smooth"); 179 180 // jQuery("#main.hmoe, .hmoe .left_grip").css("background-position-y","225px"; 181 182 // jQuery("#main.hmoe, .hmoe .left_grip").css("background-position-y",jQuery('#header').height()); 183 //jQuery("#main.hmoe, .hmoe .left_grip").css("background-position-y",); 184 185 } 186 /*Normal view*/ 187 else { 188 jQuery("#main.hmoe, .hmoe .left_grip, #main.ros, .ros .left_grip").css("background-position-y","65px").css("scroll-behavior","smooth"); 189 // not scrolled past the menu; only show the original menu. 190 191 jQuery('.cloned').hide(); 192 193 jQuery('.original').css('overflow','visible'); 194 195 jQuery('.original').css('visibility','visible'); 196 197 } 198 199} 200 201} 202 203function fancy_box(){ 204 205 jQuery("a.fancy_pop_up").fancybox(); 206 207} 208 209function addAnchorImage() { 210 var imgTags = document.getElementsByTagName("img"); 211 var imgArray = Array.from(imgTags); 212 213 for (var i = 0; i < imgArray.length; i++) { 214 var classNameImg = imgArray[i].getAttribute("class"); 215 216 if (classNameImg != null && classNameImg != undefined) { 217 var trimName = classNameImg.trim(); 218 var finalClass = trimName.substr(0, 3); 219 220 if (finalClass === "wp-" || finalClass === "ali") { 221 var imgSrc = imgArray[i].getAttribute("src"); 222 223 // Use closest('a') to find the nearest ancestor anchor tag 224 var anchorTag = jQuery(imgArray[i]).closest('a'); 225 var newLink = anchorTag.attr('href'); 226 227 if (typeof newLink === 'undefined' || openFile(newLink)) { 228 jQuery(imgArray[i]).wrap('<a href="' + imgSrc + '" class="fancy_pop_up" rel="group"></a>'); 229 } 230 } 231 } 232 } 233} 234 235function addAnchorImage_old1(){ 236 var imgTag = document.getElementsByTagName("img"); 237 var listofarr = Array.from(imgTag); 238 239 for(i=0; i < listofarr.length; i++){ 240 var classNameImg = listofarr[i].getAttribute("class"); 241 242 if(classNameImg != null && classNameImg != undefined){ 243 var trimName = classNameImg.trim() 244 var finalclass = trimName.substr(0,3); 245 if(finalclass == "wp-" || finalclass == "ali"){ 246 var classNameImg = listofarr[i].getAttribute("class"); 247 var trimClassName = classNameImg.trim() 248 var splitedClass = trimClassName.split(' '); 249 jQuery("." + splitedClass).each(function(i){ 250 251var that = jQuery(this),img_src=that.attr("src"); 252 253/*var newlink=that.parent('a').children('img').attr('src');*/ 254 255var newlink=that.parent('a').attr('href'); 256 257/*if(img_src != newlink){*/ 258 259if((typeof newlink == 'undefined') || openFile(newlink)){ 260 261that.wrap('<a href="'+img_src+'" class="fancy_pop_up" rel="group"></a>'); 262 263} 264 265}); 266 } 267 } 268 } 269} 270 271function addAnchorImage_old(){ 272 273 jQuery(".page-content img").each(function(i){ 274 275var that = jQuery(this),img_src=that.attr("src"); 276 277/*var newlink=that.parent('a').children('img').attr('src');*/ 278 279var newlink=that.parent('a').attr('href'); 280 281/*if(img_src != newlink){*/ 282 283if((typeof newlink == 'undefined') || openFile(newlink)){ 284 285that.wrap('<a href="'+img_src+'" class="fancy_pop_up" rel="group"></a>'); 286 287} 288 289}); 290 291} 292 293jQuery(window).on('load', function(){ 294 295 initRightSide(); 296 297}); 298 299 300 301function initDateRange(){ 302 303 var d = new Date(); 304 305 306
307 var month = d.getMonth()+1; 308 309 var day = d.getDate(); 310 311 312 313 var output = d.getFullYear() + '-' + ((''+month).length<2 ? '0' : '') + month + '-' + ((''+day).length<2 ? '0' : '') + day; 314 315 jQuery('.input-daterange').datepicker({ 316 317 todayBtn: "linked", 318 319 format: 'yyyy-mm-dd', 320 321 endDate: output, 322 323 autoclose:true 324 325 }); 326 327} 328 329 330 331function advance_search(){ 332 333 var clicked=jQuery(".advanced-search").attr('data-active'); 334 335 336 337jQuery(".advanced-search").on('click', function(e){ 338 339 if(clicked == 1) 340 341 { 342 343 clicked=0; 344 345 e.preventDefault(); 346 347 jQuery("#normal-search").hide(); 348 349 jQuery(".advance_search_form").slideDown(1000).show(); 350 351 } 352 353 else 354 355 { 356 357 clicked=true; 358 359 e.preventDefault(); 360 361 var v1,v2; 362 363 v1=jQuery("#datepicker input[name=start]").val(); 364 365 v2=jQuery("#datepicker input[name=end]").val(); 366 367 jQuery(".advance_search_form").slideUp(1000); 368 369 if(v1 !="" && v2 !=""){ 370 371 jQuery("#datepicker input[name=start],#datepicker input[name=end]").val(""); 372 373 }else{ 374 375 jQuery("#datepicker input[name=start],#datepicker input[name=end]").val(""); 376 377 } 378 379 380 381 jQuery("#normal-search").show(); 382 383 } 384 385}); 386 387 388} 389 390 391 392// right side open close 393 394function initRightSide(){ 395 396 var activeClass = 'active'; 397 398 var animSpeed = 500; 399 400 jQuery('.fixed-popup').each(function(){ 401 402 var hold = jQuery(this); 403 404 var opener = hold.find('.popup-opener'); 405 406 var slide = hold.find('.popup-content'); 407 408 slide.show().css({marginRight: -slide.width()}); 409 410 411 opener.mouseover( function(e){ 412 413 e.preventDefault(); 414 415 if(!hold.hasClass(activeClass)){ 416 417 hold.addClass(activeClass); 418 419 slide.stop().animate({marginRight: ''}, animSpeed); 420 421 } 422 423 else{ 424 425 hold.removeClass(activeClass); 426 427 slide.stop().animate({marginRight: -slide.width()}, animSpeed); 428 429 } 430 431 }); 432 433 }); 434 435} 436 437 438 439// scroll gallery init 440 441function initCarousel() { 442 443 jQuery('.carousel').scrollGallery({ 444 445 mask: '.mask', 446 447 slider: '.slideset', 448 449 slides: '.slide', 450 451 btnPrev: 'a.btn-prev', 452 453 btnNext: 'a.btn-next', 454 455 pagerLinks: '.pagination li', 456 457 autoRotation: false, 458 459 switchTime: 3000, 460 461 animSpeed: 500, 462 463 step: 1 464 465 }); 466 467} 468 469 470 471// content tabs init 472 473function initTabs() { 474 475 jQuery('ul.tabset').contentTabs({ 476 477 tabLinks: 'a' 478 479 }); 480 481} 482 483 484 485// accordion menu init 486 487function initAccordion() { 488 489 jQuery('ul.nav-accordion').slideAccordion({ 490 491 opener: 'a.nav-opener', 492 493 slider: 'div.nav-slide', 494 495 animSpeed: 300 496 497 }); 498 499} 500 501 502 503// align blocks height 504 505function initSameHeight() { 506 507 jQuery('.main-holder').sameHeight({ 508 509 elements: '.same-height', 510 511 flexible: true, 512 513 multiLine: true 514 515 }); 516 517} 518 519 520 521// handle flexible video size 522 523function initFitVids() { 524 525 jQuery('.video-holder').fitVids(); 526 527} 528 529 530 531/* 532 533 * jQuery Carousel plugin 534 535 */ 536 537;(function($){ 538 539 function ScrollGallery(options) { 540 541 this.options = $.extend({ 542 543 mask: 'div.mask', 544 545 slider: '>*', 546 547 slides: '>*', 548 549 activeClass:'active', 550 551 disabledClass:'disabled', 552 553 btnPrev: 'a.btn-prev', 554 555 btnNext: 'a.btn-next', 556 557 generatePagination: false, 558 559 pagerList: '<ul>', 560 561 pagerListItem: '<li><a href="#"></a></li>', 562 563 pagerListItemText: 'a', 564 565 pagerLinks: '.pagination li', 566 567 currentNumber: 'span.current-num', 568 569 totalNumber: 'span.total-num', 570 571 btnPlay: '.btn-play', 572 573 btnPause: '.btn-pause', 574 575 btnPlayPause: '.btn-play-pause', 576 577 galleryReadyClass: 'gallery-js-ready', 578 579 autorotationActiveClass: 'autorotation-active', 580 581 autorotationDisabledClass: 'autorotation-disabled', 582 583 stretchSlideToMask: false, 584 585 circularRotation: true, 586 587 disableWhileAnimating: false, 588 589 autoRotation: false, 590 591 pauseOnHover: isTouchDevice ? false : true, 592 593 maskAutoSize: false, 594 595 switchTime: 4000, 596 597 animSpeed: 600, 598 599 event:'click', 600 601 swipeThreshold: 15, 602 603 handleTouch: true, 604 605 vertical: false, 606 607 useTranslate3D: false, 608 609 step: false 610 611 }, options); 612 613 this.init(); 614 615 } 616 617 ScrollGallery.prototype = { 618 619 init: function() { 620 621 if(this.options.holder) { 622 623 this.findElements(); 624 625 this.attachEvents(); 626 627 this.refreshPosition(); 628 629 this.refreshState(true); 630 631 this.resumeRotation(); 632 633 this.makeCallback('onInit', this); 634 635 } 636 637 }, 638 639 findElements: function() { 640 641 // define dimensions proporties 642 643 this.fullSizeFunction = this.options.vertical ? 'outerHeight' : 'outerWidth'; 644 645 this.innerSizeFunction = this.options.vertical ? 'height' : 'width'; 646 647 this.slideSizeFunction = 'outerHeight';
648 649 this.maskSizeProperty = 'height'; 650 651 this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft'; 652 653 654 655 // control elements 656 657 this.gallery = jQuery(this.options.holder).addClass(this.options.galleryReadyClass); 658 659 this.mask = this.gallery.find(this.options.mask); 660 661 this.slider = this.mask.find(this.options.slider); 662 663 this.slides = this.slider.find(this.options.slides); 664 665 this.btnPrev = this.gallery.find(this.options.btnPrev); 666 667 this.btnNext = this.gallery.find(this.options.btnNext); 668 669 this.currentStep = 0; this.stepsCount = 0; 670 671 672 673 // get start index 674 675 if(this.options.step === false) { 676 677 var activeSlide = this.slides.filter('.'+this.options.activeClass); 678 679 if(activeSlide.length) { 680 681 this.currentStep = this.slides.index(activeSlide); 682 683 } 684 685 } 686 687 688 689 // calculate offsets 690 691 this.calculateOffsets(); 692 693 694 695 // create gallery pagination 696 697 if(typeof this.options.generatePagination === 'string') { 698 699 this.pagerLinks = jQuery(); 700 701 this.buildPagination(); 702 703 } else { 704 705 this.pagerLinks = this.gallery.find(this.options.pagerLinks); 706 707 this.attachPaginationEvents(); 708 709 } 710 711 712 713 // autorotation control buttons 714 715 this.btnPlay = this.gallery.find(this.options.btnPlay); 716 717 this.btnPause = this.gallery.find(this.options.btnPause); 718 719 this.btnPlayPause = this.gallery.find(this.options.btnPlayPause); 720 721 722 723 // misc elements 724 725 this.curNum = this.gallery.find(this.options.currentNumber); 726 727 this.allNum = this.gallery.find(this.options.totalNumber); 728 729 }, 730 731 attachEvents: function() { 732 733 // bind handlers scope 734 735 var self = this; 736 737 this.bindHandlers(['onWindowResize']); 738 739 jQuery(window).bind('load resize orientationchange', this.onWindowResize); 740 741 742 743 // previous and next button handlers 744 745 if(this.btnPrev.length) { 746 747 this.prevSlideHandler = function(e) { 748 749 e.preventDefault(); 750 751 self.prevSlide(); 752 753 }; 754 755 this.btnPrev.bind(this.options.event, this.prevSlideHandler); 756 757 } 758 759 if(this.btnNext.length) { 760 761 this.nextSlideHandler = function(e) { 762 763 e.preventDefault(); 764 765 self.nextSlide(); 766 767 }; 768 769 this.btnNext.bind(this.options.event, this.nextSlideHandler); 770 771 } 772 773 774 775 // pause on hover handling 776 777 if(this.options.pauseOnHover && !isTouchDevice) { 778 779 this.hoverHandler = function() { 780 781 if(self.options.autoRotation) { 782 783 self.galleryHover = true; 784 785 self.pauseRotation(); 786 787 } 788 789 }; 790 791 this.leaveHandler = function() { 792 793 if(self.options.autoRotation) { 794 795 self.galleryHover = false; 796 797 self.resumeRotation(); 798 799 } 800 801 }; 802 803 this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler}); 804 805 } 806 807 808 809 // autorotation buttons handler 810 811 if(this.btnPlay.length) { 812 813 this.btnPlayHandler = function(e) { 814 815 e.preventDefault(); 816 817 self.startRotation(); 818 819 }; 820 821 this.btnPlay.bind(this.options.event, this.btnPlayHandler); 822 823 } 824 825 if(this.btnPause.length) { 826 827 this.btnPauseHandler = function(e) { 828 829 e.preventDefault(); 830 831 self.stopRotation(); 832 833 }; 834 835 this.btnPause.bind(this.options.event, this.btnPauseHandler); 836 837 } 838 839 if(this.btnPlayPause.length) { 840 841 this.btnPlayPauseHandler = function(e) { 842 843 e.preventDefault(); 844 845 if(!self.gallery.hasClass(self.options.autorotationActiveClass)) { 846 847 self.startRotation(); 848 849 } else { 850 851 self.stopRotation(); 852 853 } 854 855 }; 856 857 this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler); 858 859 } 860 861 862 863 // enable hardware acceleration 864 865 if(isTouchDevice && this.options.useTranslate3D) { 866 867 this.slider.css({'-webkit-transform': 'translate3d(0px, 0px, 0px)'}); 868 869 } 870 871 872 873 // swipe event handling 874 875 if(isTouchDevice && this.options.handleTouch && window.Hammer && this.mask.length) { 876 877 this.swipeHandler = Hammer(this.mask[0], { 878 879 dragBlockHorizontal: !this.options.vertical, 880 881 dragBlockVertical: this.options.vertical, 882 883 dragMinDistance: 1, 884 885 behavior: { 886 887 touchAction: this.options.vertical ? 'pan-x' : 'pan-y' 888 889 } 890 891 }).on('touch release ' + (self.options.vertical ? 'dragup dragdown' : 'dragleft dragright'), function(e) { 892 893 switch(e.type) { 894 895 case 'touch': 896 897 if(self.galleryAnimating) { 898 899 e.gesture.stopDetect(); 900 901 } else { 902 903 self.pauseRotation(); 904 905 self.originalOffset = parseFloat(self.slider.css(self.animProperty)); 906 907 } 908 909 break; 910 911 case 'dragup': 912 913 case 'dragdown': 914 915 case 'dragleft': 916 917 case 'dragright': 918 919 e.gesture.preventDefault(); 920 921 var tmpOffset = self.originalOffset + e.gesture[self.options.vertical ? 'deltaY' : 'deltaX']; 922 923 tmpOffset = Math.max(Math.min(0, tmpOffset), self.maxOffset); 924 925 self.slider.css(self.animProperty, tmpOffset); 926 927 break; 928 929 case 'release': 930 931 self.resumeRotation(); 932 933 if(Math.abs(e.gesture[self.options.vertical ? 'deltaY' : 'deltaX']) > self.options.swipeThreshold) { 934 935 if(e.gesture.direction == 'left' || e.gesture.direction == 'up') { 936 937 self.nextSlide(); 938 939 } else { 940 941 self.prevSlide(); 942 943 } 944 945 } else { 946 947 self.switchSlide(); 948 949 } 950 951 } 952 953 }); 954 955 } 956 957 }, 958 959 onWindowResize: function() { 960 961 if(!this.galleryAnimating) { 962 963 this.calculateOffsets(); 964 965 this.refreshPosition(); 966 967 this.buildPagination(); 968 969 this.refreshState(); 970 971 this.resizeQueue = false;
972 973 } else { 974 975 this.resizeQueue = true; 976 977 } 978 979 }, 980 981 refreshPosition: function() { 982 983 this.currentStep = Math.min(this.currentStep, this.stepsCount - 1); 984 985 this.tmpProps = {}; 986 987 this.tmpProps[this.animProperty] = this.getStepOffset(); 988 989 this.slider.stop().css(this.tmpProps); 990 991 }, 992 993 calculateOffsets: function() { 994 995 var self = this, tmpOffset, tmpStep; 996 997 if(this.options.stretchSlideToMask) { 998 999 var tmpObj = {}; 1000 1001 tmpObj[this.innerSizeFunction] = this.mask[this.innerSizeFunction](); 1002 1003 this.slides.css(tmpObj); 1004 1005 } 1006 1007 1008 1009 this.maskSize = this.mask[this.innerSizeFunction](); 1010 1011 this.sumSize = this.getSumSize(); 1012 1013 this.maxOffset = this.maskSize - this.sumSize; 1014 1015 1016 1017 // vertical gallery with single size step custom behavior 1018 1019 if(this.options.vertical && this.options.maskAutoSize) { 1020 1021 this.options.step = 1; 1022 1023 this.stepsCount = this.slides.length; 1024 1025 this.stepOffsets = [0]; 1026 1027 tmpOffset = 0; 1028 1029 for(var i = 0; i < this.slides.length; i++) { 1030 1031 tmpOffset -= jQuery(this.slides[i])[this.fullSizeFunction](true); 1032 1033 this.stepOffsets.push(tmpOffset); 1034 1035 } 1036 1037 this.maxOffset = tmpOffset; 1038 1039 return; 1040 1041 } 1042 1043 1044 1045 // scroll by slide size 1046 1047 if(typeof this.options.step === 'number' && this.options.step > 0) { 1048 1049 this.slideDimensions = []; 1050 1051 this.slides.each($.proxy(function(ind, obj){ 1052 1053 self.slideDimensions.push( jQuery(obj)[self.fullSizeFunction](true) ); 1054 1055 },this)); 1056 1057 1058 1059 // calculate steps count 1060 1061 this.stepOffsets = [0]; 1062 1063 this.stepsCount = 1; 1064 1065 tmpOffset = tmpStep = 0; 1066 1067 while(tmpOffset > this.maxOffset) { 1068 1069 tmpOffset -= this.getSlideSize(tmpStep, tmpStep + this.options.step); 1070 1071 tmpStep += this.options.step; 1072 1073 this.stepOffsets.push(Math.max(tmpOffset, this.maxOffset)); 1074 1075 this.stepsCount++; 1076 1077 } 1078 1079 } 1080 1081 // scroll by mask size 1082 1083 else { 1084 1085 // define step size 1086 1087 this.stepSize = this.maskSize; 1088 1089 1090 1091 // calculate steps count 1092 1093 this.stepsCount = 1; 1094 1095 tmpOffset = 0; 1096 1097 while(tmpOffset > this.maxOffset) { 1098 1099 tmpOffset -= this.stepSize; 1100 1101 this.stepsCount++; 1102 1103 } 1104 1105 } 1106 1107 }, 1108 1109 getSumSize: function() { 1110 1111 var sum = 0; 1112 1113 this.slides.each($.proxy(function(ind, obj){ 1114 1115 sum += jQuery(obj)[this.fullSizeFunction](true); 1116 1117 },this)); 1118 1119 this.slider.css(this.innerSizeFunction, sum); 1120 1121 return sum; 1122 1123 }, 1124 1125 getStepOffset: function(step) { 1126 1127 step = step || this.currentStep; 1128 1129 if(typeof this.options.step === 'number') { 1130 1131 return this.stepOffsets[this.currentStep]; 1132 1133 } else { 1134 1135 return Math.min(0, Math.max(-this.currentStep * this.stepSize, this.maxOffset)); 1136 1137 } 1138 1139 }, 1140 1141 getSlideSize: function(i1, i2) { 1142 1143 var sum = 0; 1144 1145 for(var i = i1; i < Math.min(i2, this.slideDimensions.length); i++) { 1146 1147 sum += this.slideDimensions[i]; 1148 1149 } 1150 1151 return sum; 1152 1153 }, 1154 1155 buildPagination: function() { 1156 1157 if(typeof this.options.generatePagination === 'string') { 1158 1159 if(!this.pagerHolder) { 1160 1161 this.pagerHolder = this.gallery.find(this.options.generatePagination); 1162 1163 } 1164 1165 if(this.pagerHolder.length && this.oldStepsCount != this.stepsCount) { 1166 1167 this.oldStepsCount = this.stepsCount; 1168 1169 this.pagerHolder.empty(); 1170 1171 this.pagerList = jQuery(this.options.pagerList).appendTo(this.pagerHolder); 1172 1173 for(var i = 0; i < this.stepsCount; i++) { 1174 1175 jQuery(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1); 1176 1177 } 1178 1179 this.pagerLinks = this.pagerList.children(); 1180 1181 this.attachPaginationEvents(); 1182 1183 } 1184 1185 } 1186 1187 }, 1188 1189 attachPaginationEvents: function() { 1190 1191 var self = this; 1192 1193 this.pagerLinksHandler = function(e) { 1194 1195 e.preventDefault(); 1196 1197 self.numSlide(self.pagerLinks.index(e.currentTarget)); 1198 1199 }; 1200 1201 this.pagerLinks.bind(this.options.event, this.pagerLinksHandler); 1202 1203 }, 1204 1205 prevSlide: function() { 1206 1207 if(!(this.options.disableWhileAnimating && this.galleryAnimating)) { 1208 1209 if(this.currentStep > 0) { 1210 1211 this.currentStep--; 1212 1213 this.switchSlide(); 1214 1215 } else if(this.options.circularRotation) { 1216 1217 this.currentStep = this.stepsCount - 1; 1218 1219 this.switchSlide(); 1220 1221 } 1222 1223 } 1224 1225 }, 1226 1227 nextSlide: function(fromAutoRotation) { 1228 1229 if(!(this.options.disableWhileAnimating && this.galleryAnimating)) { 1230 1231 if(this.currentStep < this.stepsCount - 1) { 1232 1233 this.currentStep++; 1234 1235 this.switchSlide(); 1236 1237 } else if(this.options.circularRotation || fromAutoRotation === true) { 1238 1239 this.currentStep = 0; 1240 1241 this.switchSlide(); 1242 1243 } 1244 1245 } 1246 1247 }, 1248 1249 numSlide: function(c) { 1250 1251 if(this.currentStep != c) { 1252 1253 this.currentStep = c; 1254 1255 this.switchSlide(); 1256 1257 } 1258 1259 }, 1260 1261 switchSlide: function() { 1262 1263 var self = this; 1264 1265 this.galleryAnimating = true; 1266 1267 this.tmpProps = {}; 1268
1269 this.tmpProps[this.animProperty] = this.getStepOffset(); 1270 1271 this.slider.stop().animate(this.tmpProps, {duration: this.options.animSpeed, complete: function(){ 1272 1273 // animation complete 1274 1275 self.galleryAnimating = false; 1276 1277 if(self.resizeQueue) { 1278 1279 self.onWindowResize(); 1280 1281 } 1282 1283 1284 1285 // onchange callback 1286 1287 self.makeCallback('onChange', self); 1288 1289 self.autoRotate(); 1290 1291 }}); 1292 1293 this.refreshState(); 1294 1295 1296 1297 // onchange callback 1298 1299 this.makeCallback('onBeforeChange', this); 1300 1301 }, 1302 1303 refreshState: function(initial) { 1304 1305 if(this.options.step === 1 || this.stepsCount === this.slides.length) { 1306 1307 this.slides.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass); 1308 1309 } 1310 1311 this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass); 1312 1313 this.curNum.html(this.currentStep+1); 1314 1315 this.allNum.html(this.stepsCount); 1316 1317 1318 1319 // initial refresh 1320 1321 if(this.options.maskAutoSize && typeof this.options.step === 'number') { 1322 1323 this.tmpProps = {}; 1324 1325 this.tmpProps[this.maskSizeProperty] = this.slides.eq(Math.min(this.currentStep,this.slides.length-1))[this.slideSizeFunction](true); 1326 1327 this.mask.stop()[initial ? 'css' : 'animate'](this.tmpProps); 1328 1329 } 1330 1331 1332 1333 // disabled state 1334 1335 if(!this.options.circularRotation) { 1336 1337 this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass); 1338 1339 if(this.currentStep === 0) this.btnPrev.addClass(this.options.disabledClass); 1340 1341 if(this.currentStep === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass); 1342 1343 } 1344 1345 1346 1347 // add class if not enough slides 1348 1349 this.gallery.toggleClass('not-enough-slides', this.sumSize <= this.maskSize); 1350 1351 }, 1352 1353 startRotation: function() { 1354 1355 this.options.autoRotation = true; 1356 1357 this.galleryHover = false; 1358 1359 this.autoRotationStopped = false; 1360 1361 this.resumeRotation(); 1362 1363 }, 1364 1365 stopRotation: function() { 1366 1367 this.galleryHover = true; 1368 1369 this.autoRotationStopped = true; 1370 1371 this.pauseRotation(); 1372 1373 }, 1374 1375 pauseRotation: function() { 1376 1377 this.gallery.addClass(this.options.autorotationDisabledClass); 1378 1379 this.gallery.removeClass(this.options.autorotationActiveClass); 1380 1381 clearTimeout(this.timer); 1382 1383 }, 1384 1385 resumeRotation: function() { 1386 1387 if(!this.autoRotationStopped) { 1388 1389 this.gallery.addClass(this.options.autorotationActiveClass); 1390 1391 this.gallery.removeClass(this.options.autorotationDisabledClass); 1392 1393 this.autoRotate(); 1394 1395 } 1396 1397 }, 1398 1399 autoRotate: function() { 1400 1401 var self = this; 1402 1403 clearTimeout(this.timer); 1404 1405 if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) { 1406 1407 this.timer = setTimeout(function(){ 1408 1409 self.nextSlide(true); 1410 1411 }, this.options.switchTime); 1412 1413 } else { 1414 1415 this.pauseRotation(); 1416 1417 } 1418 1419 }, 1420 1421 bindHandlers: function(handlersList) { 1422 1423 var self = this; 1424 1425 $.each(handlersList, function(index, handler) { 1426 1427 var origHandler = self[handler]; 1428 1429 self[handler] = function() { 1430 1431 return origHandler.apply(self, arguments); 1432 1433 }; 1434 1435 }); 1436 1437 }, 1438 1439 makeCallback: function(name) { 1440 1441 if(typeof this.options[name] === 'function') { 1442 1443 var args = Array.prototype.slice.call(arguments); 1444 1445 args.shift(); 1446 1447 this.options[name].apply(this, args); 1448 1449 } 1450 1451 }, 1452 1453 destroy: function() { 1454 1455 // destroy handler 1456 1457 jQuery(window).unbind('load resize orientationchange', this.onWindowResize); 1458 1459 this.btnPrev.unbind(this.options.event, this.prevSlideHandler); 1460 1461 this.btnNext.unbind(this.options.event, this.nextSlideHandler); 1462 1463 this.pagerLinks.unbind(this.options.event, this.pagerLinksHandler); 1464 1465 this.gallery.unbind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler}); 1466 1467 1468 1469 // autorotation buttons handlers 1470 1471 this.stopRotation(); 1472 1473 this.btnPlay.unbind(this.options.event, this.btnPlayHandler); 1474 1475 this.btnPause.unbind(this.options.event, this.btnPauseHandler); 1476 1477 this.btnPlayPause.unbind(this.options.event, this.btnPlayPauseHandler); 1478 1479 1480 1481 // destroy swipe handler 1482 1483 if(this.swipeHandler) { 1484 1485 this.swipeHandler.dispose(); 1486 1487 } 1488 1489 1490 1491 // remove inline styles, classes and pagination 1492
1493 var unneededClasses = [this.options.galleryReadyClass, this.options.autorotationActiveClass, this.options.autorotationDisabledClass]; 1494 1495 this.gallery.removeClass(unneededClasses.join(' ')); 1496 1497 this.slider.add(this.slides).removeAttr('style'); 1498 1499 if(typeof this.options.generatePagination === 'string') { 1500 1501 this.pagerHolder.empty(); 1502 1503 } 1504 1505 } 1506 1507 }; 1508 1509 1510 1511 // detect device type 1512 1513 var isTouchDevice = /MSIE 10.*Touch/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; 1514 1515 1516 1517 // jquery plugin 1518 1519 $.fn.scrollGallery = function(opt){ 1520 1521 return this.each(function(){ 1522 1523 jQuery(this).data('ScrollGallery', new ScrollGallery($.extend(opt,{holder:this}))); 1524 1525 }); 1526 1527 }; 1528 1529}(jQuery)); 1530 1531 1532 1533/* 1534 1535 * jQuery Tabs plugin 1536 1537 */ 1538 1539;(function($){ 1540 1541 $.fn.contentTabs = function(o){ 1542 1543 // default options 1544 1545 var options = $.extend({ 1546 1547 activeClass:'active', 1548 1549 addToParent:false, 1550 1551 autoHeight:false, 1552 1553 autoRotate:false, 1554 1555 checkHash:false, 1556 1557 animSpeed:400, 1558 1559 switchTime:3000, 1560 1561 effect: 'none', // "fade", "slide" 1562 1563 tabLinks:'a', 1564 1565 attrib:'href', 1566 1567 event:'click' 1568 1569 },o); 1570 1571 1572 1573 return this.each(function(){ 1574 1575 var tabset = jQuery(this), tabs = jQuery(); 1576 1577 var tabLinks = tabset.find(options.tabLinks); 1578 1579 var tabLinksParents = tabLinks.parent(); 1580 1581 var prevActiveLink = tabLinks.eq(0), currentTab, animating; 1582 1583 var tabHolder; 1584 1585 1586 1587 // handle location hash 1588 1589 if(options.checkHash && tabLinks.filter('[' + options.attrib + '="' + location.hash + '"]').length) { 1590 1591 (options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass); 1592 1593 setTimeout(function() { 1594 1595 window.scrollTo(0,0); 1596 1597 },1); 1598 1599 } 1600 1601 1602 1603 // init tabLinks 1604 1605 tabLinks.each(function(){ 1606 1607 var link = jQuery(this); 1608 1609 var href = link.attr(options.attrib); 1610 1611 var parent = link.parent(); 1612 1613 href = href.substr(href.lastIndexOf('#')); 1614 1615 1616 1617 // get elements 1618 1619 var tab = jQuery(href).hide(); 1620 1621 tabs = tabs.add(tab); 1622 1623 link.data('cparent', parent); 1624 1625 link.data('ctab', tab); 1626 1627 1628 1629 // find tab holder 1630 1631 if(!tabHolder && tab.length) { 1632 1633 tabHolder = tab.parent(); 1634 1635 } 1636 1637 1638 1639 // show only active tab 1640 1641 var classOwner = options.addToParent ? parent : link; 1642 1643 if(classOwner.hasClass(options.activeClass) || (options.checkHash && location.hash === href)) { 1644 1645 classOwner.addClass(options.activeClass); 1646 1647 prevActiveLink = link; currentTab = tab; 1648 1649 tab.removeClass(tabHiddenClass).width(''); 1650 1651 contentTabsEffect[options.effect].show({tab:tab, fast:true}); 1652 1653 } else { 1654
1655 var tabWidth = tab.width(); 1656 1657 if(tabWidth) { 1658 1659 tab.width(tabWidth); 1660 1661 } 1662 1663 tab.addClass(tabHiddenClass); 1664 1665 } 1666 1667 1668 1669 // event handler 1670 1671 link.bind(options.event, function(e){ 1672 1673 if(link != prevActiveLink && !animating) { 1674 1675 switchTab(prevActiveLink, link); 1676 1677 prevActiveLink = link; 1678 1679 } 1680 1681 }); 1682 1683 if(options.attrib === 'href') { 1684 1685 link.bind('click', function(e){ 1686 1687 e.preventDefault(); 1688 1689 }); 1690 1691 } 1692 1693 }); 1694 1695 1696 1697 // tab switch function 1698 1699 function switchTab(oldLink, newLink) { 1700 1701 animating = true; 1702 1703 var oldTab = oldLink.data('ctab'); 1704 1705 var newTab = newLink.data('ctab'); 1706 1707 prevActiveLink = newLink; 1708 1709 currentTab = newTab; 1710 1711 1712 1713 // refresh pagination links 1714 1715 (options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass); 1716 1717 (options.addToParent ? newLink.data('cparent') : newLink).addClass(options.activeClass); 1718 1719 1720 1721 // hide old tab 1722 1723 resizeHolder(oldTab, true); 1724 1725 contentTabsEffect[options.effect].hide({ 1726 1727 speed: options.animSpeed, 1728 1729 tab:oldTab, 1730 1731 complete: function() { 1732 1733 // show current tab 1734 1735 resizeHolder(newTab.removeClass(tabHiddenClass).width('')); 1736 1737 contentTabsEffect[options.effect].show({ 1738 1739 speed: options.animSpeed, 1740 1741 tab:newTab, 1742 1743 complete: function() { 1744 1745 if(!oldTab.is(newTab)) { 1746 1747 oldTab.width(oldTab.width()).addClass(tabHiddenClass); 1748 1749 } 1750 1751 animating = false; 1752 1753 resizeHolder(newTab, false); 1754 1755 autoRotate(); 1756 1757 } 1758 1759 }); 1760 1761 } 1762 1763 }); 1764 1765 } 1766 1767 1768 1769 // holder auto height 1770 1771 function resizeHolder(block, state) { 1772 1773 var curBlock = block && block.length ? block : currentTab; 1774 1775 if(options.autoHeight && curBlock) { 1776 1777 tabHolder.stop(); 1778 1779 if(state === false) { 1780 1781 tabHolder.css({height:''}); 1782 1783 } else { 1784 1785 var origStyles = curBlock.attr('style'); 1786 1787 curBlock.show().css({width:curBlock.width()}); 1788 1789 var tabHeight = curBlock.outerHeight(true); 1790 1791 if(!origStyles) curBlock.removeAttr('style'); else curBlock.attr('style', origStyles); 1792 1793 if(state === true) { 1794 1795 tabHolder.css({height: tabHeight}); 1796 1797 } else { 1798 1799 tabHolder.animate({height: tabHeight}, {duration: options.animSpeed}); 1800 1801 } 1802 1803 } 1804 1805 } 1806 1807 } 1808 1809 if(options.autoHeight) { 1810 1811 jQuery(window).bind('resize orientationchange', function(){ 1812 1813 tabs.not(currentTab).removeClass(tabHiddenClass).show().each(function(){ 1814 1815 var tab = jQuery(this), tabWidth = tab.css({width:''}).width(); 1816 1817 if(tabWidth) { 1818 1819 tab.width(tabWidth); 1820 1821 } 1822 1823 }).hide().addClass(tabHiddenClass); 1824 1825 1826 1827 resizeHolder(currentTab, false); 1828 1829 }); 1830 1831 } 1832 1833 1834 1835 // autorotation handling 1836 1837 var rotationTimer; 1838 1839 function nextTab() { 1840 1841 var activeItem = (options.addToParent ? tabLinksParents : tabLinks).filter('.' + options.activeClass); 1842 1843 var activeIndex = (options.addToParent ? tabLinksParents : tabLinks).index(activeItem); 1844 1845 var newLink = tabLinks.eq(activeIndex < tabLinks.length - 1 ? activeIndex + 1 : 0); 1846 1847 prevActiveLink = tabLinks.eq(activeIndex); 1848 1849 switchTab(prevActiveLink, newLink); 1850 1851 } 1852 1853 function autoRotate() { 1854 1855 if(options.autoRotate && tabLinks.length > 1) { 1856 1857 clearTimeout(rotationTimer); 1858 1859 rotationTimer = setTimeout(function() { 1860 1861 if(!animating) { 1862 1863 nextTab(); 1864 1865 } else { 1866 1867 autoRotate(); 1868 1869 } 1870 1871 }, options.switchTime); 1872 1873 } 1874 1875 } 1876 1877 autoRotate(); 1878 1879 }); 1880 1881 }; 1882 1883 1884 1885 // add stylesheet for tabs on DOMReady 1886 1887 var tabHiddenClass = 'js-tab-hidden'; 1888 1889 jQuery(function() { 1890 1891 var tabStyleSheet = jQuery('<style type="text/css">')[0]; 1892 1893 var tabStyleRule = '.'+tabHiddenClass; 1894 1895 tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}'; 1896 1897 if (tabStyleSheet.styleSheet) { 1898 1899 tabStyleSheet.styleSheet.cssText = tabStyleRule; 1900 1901 } else { 1902 1903 tabStyleSheet.appendChild(document.createTextNode(tabStyleRule)); 1904 1905 } 1906 1907 jQuery('head').append(tabStyleSheet); 1908 1909 }); 1910 1911 1912 1913 // tab switch effects 1914 1915 var contentTabsEffect = { 1916 1917 none: { 1918 1919 show: function(o) { 1920 1921 o.tab.css({display:'block'}); 1922 1923 if(o.complete) o.complete(); 1924 1925 }, 1926 1927 hide: function(o) { 1928 1929 o.tab.css({display:'none'}); 1930 1931 if(o.complete) o.complete(); 1932 1933 } 1934 1935 }, 1936 1937 fade: { 1938 1939 show: function(o) { 1940 1941 if(o.fast) o.speed = 1; 1942 1943 o.tab.fadeIn(o.speed); 1944 1945 if(o.complete) setTimeout(o.complete, o.speed); 1946 1947 }, 1948 1949 hide: function(o) { 1950 1951 if(o.fast) o.speed = 1; 1952 1953 o.tab.fadeOut(o.speed); 1954 1955 if(o.complete) setTimeout(o.complete, o.speed); 1956 1957 } 1958 1959 }, 1960 1961 slide: { 1962 1963 show: function(o) { 1964 1965 var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true); 1966 1967 var tmpWrap = jQuery('<div class="effect-div">').insertBefore(o.tab).append(o.tab); 1968 1969 tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); o.tab.css({marginTop:-tabHeight,display:'block'}); 1970 1971 if(o.fast) o.speed = 1; 1972 1973 o.tab.animate({marginTop: 0}, {duration: o.speed, complete: function(){ 1974 1975 o.tab.css({marginTop: '', width: ''}).insertBefore(tmpWrap); 1976 1977 tmpWrap.remove(); 1978 1979 if(o.complete) o.complete(); 1980 1981 }}); 1982 1983 }, 1984 1985 hide: function(o) { 1986 1987 var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true); 1988 1989 var tmpWrap = jQuery('<div class="effect-div">').insertBefore(o.tab).append(o.tab); 1990 1991 tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); 1992 1993 1994 1995 if(o.fast) o.speed = 1; 1996 1997 o.tab.animate({marginTop: -tabHeight}, {duration: o.speed, complete: function(){ 1998 1999 o.tab.css({display:'none', marginTop:'', width:''}).insertBefore(tmpWrap); 2000 2001 tmpWrap.remove(); 2002 2003 if(o.complete) o.complete(); 2004 2005 }}); 2006 2007 } 2008 2009 } 2010 2011 }; 2012 2013}(jQuery)); 2014 2015 2016 2017/* 2018 2019 * jQuery Accordion plugin 2020 2021 */ 2022 2023;(function($){ 2024 2025 $.fn.slideAccordion = function(opt){ 2026 2027 // default options 2028 2029 var options = $.extend({ 2030 2031 addClassBeforeAnimation: false, 2032 2033 allowClickWhenExpanded: false, 2034 2035 activeClass:'active', 2036 2037 opener:'.opener', 2038 2039 slider:'.slide', 2040 2041 animSpeed: 300, 2042 2043 collapsible:true, 2044 2045 event:'click' 2046 2047 },opt); 2048 2049 2050 2051 return this.each(function(){ 2052 2053 // options 2054 2055 var accordion = jQuery(this); 2056 2057 var items = accordion.find(':has('+options.slider+')'); 2058 2059 2060 2061 items.each(function(){ 2062 2063 var item = jQuery(this); 2064 2065 var opener = item.find(options.opener); 2066 2067 var slider = item.find(options.slider); 2068 2069 opener.bind(options.event, function(e){ 2070
2071 if(!slider.is(':animated')) { 2072 2073 if(item.hasClass(options.activeClass)) { 2074 2075 if(options.allowClickWhenExpanded) { 2076 2077 return; 2078 2079 } else if(options.collapsible) { 2080 2081 slider.slideUp(options.animSpeed, function(){ 2082 2083 hideSlide(slider); 2084 2085 item.removeClass(options.activeClass); 2086 2087 }); 2088 2089 } 2090 2091 } else { 2092 2093 // show active 2094 2095 var levelItems = item.siblings('.'+options.activeClass); 2096 2097 var sliderElements = levelItems.find(options.slider); 2098 2099 item.addClass(options.activeClass); 2100 2101 showSlide(slider).hide().slideDown(options.animSpeed); 2102 2103 2104 2105 // collapse others 2106 2107 sliderElements.slideUp(options.animSpeed, function(){ 2108 2109 levelItems.removeClass(options.activeClass); 2110 2111 hideSlide(sliderElements); 2112 2113 }); 2114 2115 } 2116 2117 } 2118 2119 e.preventDefault(); 2120 2121 }); 2122 2123 if(item.hasClass(options.activeClass)) showSlide(slider); else hideSlide(slider); 2124 2125 }); 2126 2127 }); 2128 2129 }; 2130 2131 2132 2133 // accordion slide visibility 2134 2135 var showSlide = function(slide) { 2136 2137 return slide.css({position:'', top: '', left: '', width: '' }); 2138 2139 }; 2140 2141 var hideSlide = function(slide) { 2142 2143 return slide.show().css({position:'absolute', top: -9999, left: -9999, width: slide.width() }); 2144 2145 }; 2146 2147}(jQuery)); 2148 2149 2150 2151/* 2152 2153 * jQuery SameHeight plugin 2154 2155 */ 2156 2157;(function($){ 2158 2159 $.fn.sameHeight = function(opt) { 2160 2161 var options = $.extend({ 2162 2163 skipClass: 'same-height-ignore', 2164 2165 leftEdgeClass: 'same-height-left', 2166 2167 rightEdgeClass: 'same-height-right', 2168 2169 elements: '>*', 2170 2171 flexible: false, 2172 2173 multiLine: false, 2174 2175 useMinHeight: false, 2176 2177 biggestHeight: false 2178 2179 },opt); 2180 2181 return this.each(function(){ 2182 2183 var holder = jQuery(this), postResizeTimer, ignoreResize; 2184 2185 var elements = holder.find(options.elements).not('.' + options.skipClass); 2186 2187 if(!elements.length) return; 2188 2189 2190 2191 // resize handler 2192 2193 function doResize() { 2194 2195 elements.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', ''); 2196 2197 if(options.multiLine) { 2198 2199 // resize elements row by row 2200 2201 resizeElementsByRows(elements, options); 2202 2203 } else { 2204 2205 // resize elements by holder 2206 2207 resizeElements(elements, holder, options); 2208 2209 } 2210 2211 } 2212 2213 doResize(); 2214 2215 2216 2217 // handle flexible layout / font resize 2218 2219 var delayedResizeHandler = function() { 2220 2221 if(!ignoreResize) { 2222 2223 ignoreResize = true; 2224 2225 doResize(); 2226 2227 clearTimeout(postResizeTimer); 2228 2229 postResizeTimer = setTimeout(function() { 2230 2231 doResize(); 2232 2233 setTimeout(function(){ 2234 2235 ignoreResize = false; 2236 2237 }, 10); 2238 2239 }, 100); 2240 2241 } 2242 2243 }; 2244 2245 2246 2247 // handle flexible/responsive layout 2248 2249 if(options.flexible) { 2250 2251 jQuery(window).bind('resize orientationchange fontresize', delayedResizeHandler); 2252 2253 } 2254 2255 2256 2257 // handle complete page load including images and fonts 2258 2259 jQuery(window).bind('load', delayedResizeHandler); 2260 2261 }); 2262 2263 }; 2264 2265 2266 2267 // detect css min-height support 2268 2269 var supportMinHeight = typeof document.documentElement.style.maxHeight !== 'undefined'; 2270 2271 2272 2273 // get elements by rows 2274 2275 function resizeElementsByRows(boxes, options) { 2276 2277 var currentRow = jQuery(), maxHeight, maxCalcHeight = 0, firstOffset = boxes.eq(0).offset().top; 2278 2279 boxes.each(function(ind){ 2280 2281 var curItem = jQuery(this); 2282 2283 if(curItem.offset().top === firstOffset) { 2284 2285 currentRow = currentRow.add(this); 2286 2287 } else { 2288 2289 maxHeight = getMaxHeight(currentRow); 2290 2291 maxCalcHeight = Math.max(maxCalcHeight, resizeElements(currentRow, maxHeight, options)); 2292 2293 currentRow = curItem; 2294 2295 firstOffset = curItem.offset().top; 2296 2297 } 2298 2299 }); 2300 2301 if(currentRow.length) { 2302 2303 maxHeight = getMaxHeight(currentRow); 2304 2305 maxCalcHeight = Math.max(maxCalcHeight, resizeElements(currentRow, maxHeight, options)); 2306 2307 } 2308 2309 if(options.biggestHeight) { 2310 2311 boxes.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', maxCalcHeight); 2312 2313 } 2314 2315 } 2316 2317 2318 2319 // calculate max element height 2320 2321 function getMaxHeight(boxes) { 2322 2323 var maxHeight = 0; 2324 2325 boxes.each(function(){ 2326 2327 maxHeight = Math.max(maxHeight, jQuery(this).outerHeight()); 2328 2329 }); 2330 2331 return maxHeight; 2332 2333 } 2334 2335 2336 2337 // resize helper function 2338 2339 function resizeElements(boxes, parent, options) { 2340 2341 var calcHeight; 2342 2343 var parentHeight = typeof parent === 'number' ? parent : parent.height(); 2344 2345 boxes.removeClass(options.leftEdgeClass).removeClass(options.rightEdgeClass).each(function(i){ 2346 2347 var element = jQuery(this); 2348 2349 var depthDiffHeight = 0; 2350 2351 var isBorderBox = element.css('boxSizing') === 'border-box' || element.css('-moz-box-sizing') === 'border-box' || element.css('-webkit-box-sizing') === 'border-box'; 2352 2353 2354 2355 if(typeof parent !== 'number') { 2356 2357 element.parents().each(function(){ 2358 2359 var tmpParent = jQuery(this); 2360 2361 if(parent.is(this)) { 2362 2363 return false;
2364 2365 } else { 2366 2367 depthDiffHeight += tmpParent.outerHeight() - tmpParent.height(); 2368 2369 } 2370 2371 }); 2372 2373 } 2374 2375 calcHeight = parentHeight - depthDiffHeight; 2376 2377 calcHeight -= isBorderBox ? 0 : element.outerHeight() - element.height(); 2378 2379 2380 2381 if(calcHeight > 0) { 2382 2383 element.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', calcHeight); 2384 2385 } 2386 2387 }); 2388 2389 boxes.filter(':first').addClass(options.leftEdgeClass); 2390 2391 boxes.filter(':last').addClass(options.rightEdgeClass); 2392 2393 return calcHeight; 2394 2395 } 2396 2397}(jQuery)); 2398 2399 2400 2401/* 2402 2403 * jQuery FontResize Event 2404 2405 */ 2406 2407jQuery.onFontResize = (function($) { 2408 2409 jQuery(function() { 2410 2411 var randomID = 'font-resize-frame-' + Math.floor(Math.random() * 1000); 2412 2413 var resizeFrame = jQuery('<iframe>').attr('id', randomID).addClass('font-resize-helper'); 2414 2415 2416 2417 // required styles 2418 2419 resizeFrame.css({ 2420 2421 width: '100em', 2422 2423 height: '10px', 2424 2425 position: 'absolute', 2426 2427 borderWidth: 0, 2428 2429 top: '-9999px', 2430 2431 left: '-9999px' 2432 2433 }).appendTo('body'); 2434 2435 2436 2437 // use native IE resize event if possible 2438 2439 if (window.attachEvent && !window.addEventListener) { 2440 2441 resizeFrame.bind('resize', function () { 2442 2443 $.onFontResize.trigger(resizeFrame[0].offsetWidth / 100); 2444 2445 }); 2446 2447 } 2448 2449 // use script inside the iframe to detect resize for other browsers 2450 2451 else { 2452 2453 var doc = resizeFrame[0].contentWindow.document; 2454 2455 doc.open(); 2456 2457 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>'); 2458 2459 doc.close(); 2460 2461 } 2462
2463 jQuery.onFontResize.initialSize = resizeFrame[0].offsetWidth / 100; 2464 2465 }); 2466 2467 return { 2468 2469 // public method, so it can be called from within the iframe 2470 2471 trigger: function (em) { 2472 2473 jQuery(window).trigger("fontresize", [em]); 2474 2475 } 2476 2477 }; 2478 2479}(jQuery)); 2480 2481 2482 2483/*! http://mths.be/placeholder v2.0.7 by @mathias */ 2484 2485;(function(window, document, $) { 2486 2487 2488 2489 // Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so 2490 2491 var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]'; 2492 2493 var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini; 2494 2495 var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini; 2496 2497 var prototype = $.fn; 2498 2499 var valHooks = $.valHooks; 2500 2501 var propHooks = $.propHooks; 2502 2503 var hooks; 2504 2505 var placeholder; 2506 2507 2508 2509 if (isInputSupported && isTextareaSupported) { 2510 2511 2512 2513 placeholder = prototype.placeholder = function() { 2514 2515 return this; 2516 2517 }; 2518 2519 2520 2521 placeholder.input = placeholder.textarea = true; 2522 2523 2524 2525 } else { 2526 2527 2528 2529 placeholder = prototype.placeholder = function() { 2530 2531 var $this = this; 2532 2533 $this 2534 2535 .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]') 2536 2537 .not('.placeholder') 2538 2539 .bind({ 2540 2541 'focus.placeholder': clearPlaceholder, 2542 2543 'blur.placeholder': setPlaceholder 2544 2545 }) 2546 2547 .data('placeholder-enabled', true) 2548 2549 .trigger('blur.placeholder'); 2550 2551 return $this; 2552 2553 }; 2554 2555 2556 2557 placeholder.input = isInputSupported; 2558 2559 placeholder.textarea = isTextareaSupported; 2560 2561 2562 2563 hooks = { 2564 2565 'get': function(element) { 2566 2567 var $element = jQuery(element); 2568 2569 2570 2571 var $passwordInput = $element.data('placeholder-password'); 2572 2573 if ($passwordInput) { 2574 2575 return $passwordInput[0].value; 2576 2577 } 2578 2579 2580 2581 return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value; 2582 2583 }, 2584 2585 'set': function(element, value) { 2586 2587 var $element = jQuery(element); 2588 2589 2590 2591 var $passwordInput = $element.data('placeholder-password'); 2592 2593 if ($passwordInput) { 2594 2595 return $passwordInput[0].value = value; 2596 2597 } 2598 2599 2600 2601 if (!$element.data('placeholder-enabled')) { 2602 2603 return element.value = value; 2604 2605 } 2606 2607 if (value == '') { 2608 2609 element.value = value; 2610 2611 // Issue #56: Setting the placeholder causes problems if the element continues to have focus. 2612 2613 if (element != safeActiveElement()) { 2614 2615 // We can't use `triggerHandler` here because of dummy text/password inputs :( 2616 2617 setPlaceholder.call(element); 2618 2619 } 2620 2621 } else if ($element.hasClass('placeholder')) { 2622 2623 clearPlaceholder.call(element, true, value) || (element.value = value); 2624 2625 } else { 2626 2627 element.value = value; 2628 2629 } 2630 2631 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 2632 2633 return $element; 2634 2635 } 2636 2637 }; 2638 2639 2640 2641 if (!isInputSupported) { 2642 2643 valHooks.input = hooks; 2644 2645 propHooks.value = hooks; 2646 2647 } 2648 2649 if (!isTextareaSupported) { 2650 2651 valHooks.textarea = hooks; 2652 2653 propHooks.value = hooks; 2654 2655 } 2656 2657 2658 2659 jQuery(function() { 2660 2661 // Look for forms 2662 2663 jQuery(document).delegate('form', 'submit.placeholder', function() { 2664 2665 // Clear the placeholder values so they don't get submitted 2666 2667 var $inputs = jQuery('.placeholder', this).each(clearPlaceholder); 2668 2669 setTimeout(function() { 2670 2671 $inputs.each(setPlaceholder); 2672 2673 }, 10); 2674 2675 }); 2676 2677 }); 2678 2679 2680 2681 // Clear placeholder values upon page reload 2682 2683 jQuery(window).bind('beforeunload.placeholder', function() { 2684 2685 jQuery('.placeholder').each(function() { 2686 2687 this.value = ''; 2688 2689 }); 2690 2691 }); 2692 2693 2694 2695 } 2696 2697 2698 2699 function args(elem) { 2700 2701 // Return an object of element attributes 2702 2703 var newAttrs = {}; 2704 2705 var rinlinejQuery = /^jQuery\d+$/; 2706 2707 $.each(elem.attributes, function(i, attr) { 2708 2709 if (attr.specified && !rinlinejQuery.test(attr.name)) { 2710 2711 newAttrs[attr.name] = attr.value; 2712 2713 } 2714 2715 }); 2716 2717 return newAttrs; 2718 2719 } 2720 2721 2722 2723 function clearPlaceholder(event, value) { 2724 2725 var input = this; 2726 2727 var $input = jQuery(input); 2728 2729 if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) { 2730 2731 if ($input.data('placeholder-password')) { 2732 2733 $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id')); 2734 2735 // If `clearPlaceholder` was called from `$.valHooks.input.set` 2736 2737 if (event === true) { 2738 2739 return $input[0].value = value; 2740 2741 } 2742 2743 $input.focus(); 2744 2745 } else { 2746 2747 input.value = ''; 2748 2749 $input.removeClass('placeholder'); 2750 2751 input == safeActiveElement() && input.select(); 2752 2753 } 2754 2755 } 2756 2757 } 2758 2759 2760 2761 function setPlaceholder() { 2762 2763 var $replacement; 2764 2765 var input = this; 2766 2767 var $input = jQuery(input); 2768 2769 var id = this.id; 2770 2771 if (input.value == '') { 2772 2773 if (input.type == 'password') { 2774 2775 if (!$input.data('placeholder-textinput')) { 2776 2777 try { 2778 2779 $replacement = $input.clone().attr({ 'type': 'text' }); 2780 2781 } catch(e) { 2782 2783 $replacement = jQuery('<input>').attr($.extend(args(this), { 'type': 'text' })); 2784 2785 } 2786 2787 $replacement 2788 2789 .removeAttr('name') 2790 2791 .data({ 2792 2793 'placeholder-password': $input, 2794 2795 'placeholder-id': id 2796 2797 }) 2798 2799 .bind('focus.placeholder', clearPlaceholder); 2800 2801 $input 2802 2803 .data({ 2804 2805 'placeholder-textinput': $replacement, 2806 2807 'placeholder-id': id 2808 2809 }) 2810 2811 .before($replacement); 2812 2813 } 2814 2815 $input = $input.removeAttr('id').hide().prev().attr('id', id).show(); 2816 2817 // Note: `$input[0] != input` now! 2818 2819 } 2820 2821 $input.addClass('placeholder'); 2822 2823 $input[0].value = $input.attr('placeholder'); 2824 2825 } else { 2826 2827 $input.removeClass('placeholder'); 2828 2829 } 2830 2831 } 2832 2833 2834 2835 function safeActiveElement() { 2836 2837 // Avoid IE9 `document.activeElement` of death 2838 2839 // https://github.com/mathiasbynens/jquery-placeholder/pull/99 2840 2841 try { 2842 2843 return document.activeElement; 2844 2845 } catch (err) {} 2846 2847 } 2848 2849 2850 2851}(this, document, jQuery)); 2852 2853 2854 2855/* 2856 2857 * JavaScript Custom Forms Module 2858 2859 */ 2860 2861jcf = { 2862 2863 // global options 2864 2865 modules: {}, 2866 2867 plugins: {}, 2868 2869 baseOptions: { 2870 2871 unselectableClass:'jcf-unselectable', 2872 2873 labelActiveClass:'jcf-label-active', 2874 2875 labelDisabledClass:'jcf-label-disabled', 2876 2877 classPrefix: 'jcf-class-', 2878 2879 hiddenClass:'jcf-hidden', 2880 2881 focusClass:'jcf-focus', 2882 2883 wrapperTag: 'div' 2884 2885 }, 2886 2887 // replacer function 2888 2889 customForms: { 2890 2891 setOptions: function(obj) { 2892 2893 for(var p in obj) { 2894 2895 if(obj.hasOwnProperty(p) && typeof obj[p] === 'object') { 2896 2897 jcf.lib.extend(jcf.modules[p].prototype.defaultOptions, obj[p]); 2898 2899 } 2900 2901 } 2902 2903 }, 2904 2905 replaceAll: function(context) { 2906 2907 for(var k in jcf.modules) { 2908 2909 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector, context); 2910
2911 for(var i = 0; i<els.length; i++) { 2912 2913 if(els[i].jcf) { 2914 2915 // refresh form element state 2916 2917 els[i].jcf.refreshState(); 2918 2919 } else { 2920 2921 // replace form element 2922 2923 if(!jcf.lib.hasClass(els[i], 'default') && jcf.modules[k].prototype.checkElement(els[i])) { 2924 2925 new jcf.modules[k]({ 2926 2927 replaces:els[i] 2928 2929 }); 2930 2931 } 2932 2933 } 2934 2935 } 2936 2937 } 2938 2939 }, 2940 2941 refreshAll: function(context) { 2942 2943 for(var k in jcf.modules) { 2944 2945 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector, context); 2946 2947 for(var i = 0; i<els.length; i++) { 2948 2949 if(els[i].jcf) { 2950 2951 // refresh form element state 2952 2953 els[i].jcf.refreshState(); 2954 2955 } 2956 2957 } 2958 2959 } 2960 2961 }, 2962 2963 refreshElement: function(obj) { 2964 2965 if(obj && obj.jcf) { 2966 2967 obj.jcf.refreshState(); 2968 2969 } 2970 2971 }, 2972 2973 destroyAll: function() { 2974 2975 for(var k in jcf.modules) { 2976 2977 var els = jcf.lib.queryBySelector(jcf.modules[k].prototype.selector); 2978 2979 for(var i = 0; i<els.length; i++) { 2980 2981 if(els[i].jcf) { 2982 2983 els[i].jcf.destroy(); 2984 2985 } 2986 2987 } 2988 2989 } 2990 2991 } 2992 2993 }, 2994 2995 // detect device type 2996 2997 isTouchDevice: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch, 2998 2999 isWinPhoneDevice: navigator.msPointerEnabled && /MSIE 10.*Touch/.test(navigator.userAgent), 3000 3001 // define base module 3002 3003 setBaseModule: function(obj) { 3004 3005 jcf.customControl = function(opt){ 3006 3007 this.options = jcf.lib.extend({}, jcf.baseOptions, this.defaultOptions, opt); 3008 3009 this.init(); 3010 3011 }; 3012 3013 for(var p in obj) { 3014 3015 jcf.customControl.prototype[p] = obj[p]; 3016 3017 } 3018 3019 }, 3020 3021 // add module to jcf.modules 3022 3023 addModule: function(obj) { 3024 3025 if(obj.name){ 3026 3027 // create new module proto class 3028 3029 jcf.modules[obj.name] = function(){ 3030 3031 jcf.modules[obj.name].superclass.constructor.apply(this, arguments); 3032 3033 } 3034 3035 jcf.lib.inherit(jcf.modules[obj.name], jcf.customControl); 3036 3037 for(var p in obj) { 3038 3039 jcf.modules[obj.name].prototype[p] = obj[p] 3040 3041 } 3042 3043 // on create module 3044 3045 jcf.modules[obj.name].prototype.onCreateModule(); 3046 3047 // make callback for exciting modules 3048 3049 for(var mod in jcf.modules) { 3050 3051 if(jcf.modules[mod] != jcf.modules[obj.name]) { 3052 3053 jcf.modules[mod].prototype.onModuleAdded(jcf.modules[obj.name]); 3054 3055 } 3056 3057 } 3058 3059 } 3060 3061 }, 3062 3063 // add plugin to jcf.plugins 3064 3065 addPlugin: function(obj) { 3066 3067 if(obj && obj.name) { 3068 3069 jcf.plugins[obj.name] = function() { 3070 3071 this.init.apply(this, arguments); 3072 3073 } 3074 3075 for(var p in obj) { 3076 3077 jcf.plugins[obj.name].prototype[p] = obj[p]; 3078 3079 } 3080 3081 } 3082 3083 }, 3084 3085 // miscellaneous init 3086 3087 init: function(){ 3088 3089 if(navigator.pointerEnabled || navigator.msPointerEnabled) { 3090 3091 // use pointer events instead of mouse events 3092 3093 this.eventPress = navigator.pointerEnabled ? 'pointerdown' : 'MSPointerDown'; 3094 3095 this.eventMove = navigator.pointerEnabled ? 'pointermove' : 'MSPointerMove'; 3096 3097 this.eventRelease = navigator.pointerEnabled ? 'pointerup' : 'MSPointerUp'; 3098 3099 } else { 3100 3101 // handle default desktop mouse events 3102 3103 this.eventPress = 'mousedown'; 3104 3105 this.eventMove = 'mousemove'; 3106 3107 this.eventRelease = 'mouseup'; 3108 3109 } 3110 3111 if(this.isTouchDevice) { 3112 3113 // handle touch events also 3114 3115 this.eventPress += ' touchstart'; 3116 3117 this.eventMove += ' touchmove'; 3118 3119 this.eventRelease += ' touchend'; 3120 3121 } 3122 3123 3124 3125 setTimeout(function(){ 3126 3127 jcf.lib.domReady(function(){ 3128 3129 jcf.initStyles(); 3130 3131 }); 3132 3133 },1); 3134 3135 return this; 3136 3137 }, 3138 3139 initStyles: function() { 3140 3141 // create <style> element and rules 3142 3143 var head = document.getElementsByTagName('head')[0], 3144 3145 style = document.createElement('style'), 3146 3147 rules = document.createTextNode('.'+jcf.baseOptions.unselectableClass+'{'+ 3148 3149 '-moz-user-select:none;'+ 3150 3151 '-webkit-tap-highlight-color:rgba(255,255,255,0);'+ 3152 3153 '-webkit-user-select:none;'+ 3154 3155 'user-select:none;'+ 3156 3157 '}'); 3158 3159 3160 3161 // append style element 3162 3163 style.type = 'text/css'; 3164 3165 if(style.styleSheet) { 3166 3167 style.styleSheet.cssText = rules.nodeValue; 3168 3169 } else { 3170 3171 style.appendChild(rules); 3172 3173 } 3174 3175 head.appendChild(style); 3176 3177 } 3178 3179}.init(); 3180 3181 3182 3183/* 3184 3185 * Custom Form Control prototype 3186 3187 */ 3188 3189jcf.setBaseModule({ 3190 3191 init: function(){ 3192 3193 if(this.options.replaces) { 3194 3195 this.realElement = this.options.replaces; 3196 3197 this.realElement.jcf = this; 3198 3199 this.replaceObject(); 3200 3201 } 3202 3203 }, 3204 3205 defaultOptions: { 3206 3207 // default module options (will be merged with base options) 3208 3209 }, 3210 3211 checkElement: function(el){ 3212 3213 return true;
3213 // additional check for correct form element 3214 3215 }, 3216 3217 replaceObject: function(){ 3218 3219 this.createWrapper(); 3220 3221 this.attachEvents(); 3222 3223 this.fixStyles(); 3224 3225 this.setupWrapper(); 3226 3227 }, 3228 3229 createWrapper: function(){ 3230 3231 this.fakeElement = jcf.lib.createElement(this.options.wrapperTag); 3232 3233 this.labelFor = jcf.lib.getLabelFor(this.realElement); 3234 3235 jcf.lib.disableTextSelection(this.fakeElement); 3236 3237 jcf.lib.addClass(this.fakeElement, jcf.lib.getAllClasses(this.realElement.className, this.options.classPrefix)); 3238 3239 jcf.lib.addClass(this.realElement, jcf.baseOptions.hiddenClass); 3240 3241 }, 3242 3243 attachEvents: function(){ 3244 3245 jcf.lib.event.add(this.realElement, 'focus', this.onFocusHandler, this); 3246 3247 jcf.lib.event.add(this.realElement, 'blur', this.onBlurHandler, this); 3248 3249 jcf.lib.event.add(this.fakeElement, 'click', this.onFakeClick, this); 3250 3251 jcf.lib.event.add(this.fakeElement, jcf.eventPress, this.onFakePressed, this); 3252 3253 jcf.lib.event.add(this.fakeElement, jcf.eventRelease, this.onFakeReleased, this); 3254 3255 3256 3257 if(this.labelFor) { 3258 3259 this.labelFor.jcf = this; 3260 3261 jcf.lib.event.add(this.labelFor, 'click', this.onFakeClick, this); 3262 3263 jcf.lib.event.add(this.labelFor, jcf.eventPress, this.onFakePressed, this); 3264 3265 jcf.lib.event.add(this.labelFor, jcf.eventRelease, this.onFakeReleased, this); 3266 3267 } 3268 3269 }, 3270 3271 fixStyles: function() { 3272 3273 // hide mobile webkit tap effect 3274 3275 if(jcf.isTouchDevice) { 3276 3277 var tapStyle = 'rgba(255,255,255,0)'; 3278 3279 this.realElement.style.webkitTapHighlightColor = tapStyle; 3280 3281 this.fakeElement.style.webkitTapHighlightColor = tapStyle; 3282 3283 if(this.labelFor) { 3284 3285 this.labelFor.style.webkitTapHighlightColor = tapStyle; 3286 3287 } 3288 3289 } 3290 3291 }, 3292 3293 setupWrapper: function(){ 3294 3295 // implement in subclass 3296 3297 }, 3298 3299 refreshState: function(){ 3300 3301 // implement in subclass 3302 3303 }, 3304 3305 destroy: function() { 3306 3307 if(this.fakeElement && this.fakeElement.parentNode) { 3308 3309 this.fakeElement.parentNode.insertBefore(this.realElement, this.fakeElement); 3310 3311 this.fakeElement.parentNode.removeChild(this.fakeElement); 3312 3313 } 3314 3315 jcf.lib.removeClass(this.realElement, jcf.baseOptions.hiddenClass); 3316 3317 this.realElement.jcf = null; 3318 3319 }, 3320 3321 onFocus: function(){ 3322 3323 // emulated focus event 3324 3325 jcf.lib.addClass(this.fakeElement,this.options.focusClass); 3326 3327 }, 3328 3329 onBlur: function(cb){ 3330 3331 // emulated blur event 3332 3333 jcf.lib.removeClass(this.fakeElement,this.options.focusClass); 3334 3335 }, 3336 3337 onFocusHandler: function() { 3338 3339 // handle focus loses 3340 3341 if(this.focused) return; 3342 3343 this.focused = true; 3344 3345 3346 3347 // handle touch devices also 3348 3349 if(jcf.isTouchDevice) { 3350 3351 if(jcf.focusedInstance && jcf.focusedInstance.realElement != this.realElement) { 3352 3353 jcf.focusedInstance.onBlur(); 3354 3355 jcf.focusedInstance.realElement.blur(); 3356 3357 } 3358 3359 jcf.focusedInstance = this; 3360 3361 } 3362 3363 this.onFocus.apply(this, arguments); 3364 3365 }, 3366 3367 onBlurHandler: function() { 3368 3369 // handle focus loses 3370 3371 if(!this.pressedFlag) { 3372 3373 this.focused = false; 3374 3375 this.onBlur.apply(this, arguments); 3376 3377 } 3378 3379 }, 3380 3381 onFakeClick: function(){ 3382 3383 if(jcf.isTouchDevice) { 3384 3385 this.onFocus(); 3386 3387 } else if(!this.realElement.disabled) { 3388 3389 this.realElement.focus(); 3390 3391 } 3392 3393 }, 3394 3395 onFakePressed: function(e){ 3396 3397 this.pressedFlag = true; 3398 3399 }, 3400 3401 onFakeReleased: function(){ 3402 3403 this.pressedFlag = false; 3404 3405 }, 3406 3407 onCreateModule: function(){ 3408 3409 // implement in subclass 3410 3411 }, 3412 3413 onModuleAdded: function(module) { 3414 3415 // implement in subclass 3416 3417 }, 3418 3419 onControlReady: function() { 3420 3421 // implement in subclass 3422 3423 } 3424 3425}); 3426 3427 3428 3429/* 3430 3431 * JCF Utility Library 3432 3433 */ 3434 3435jcf.lib = { 3436 3437 bind: function(func, scope){ 3438 3439 return function() { 3440 3441 return func.apply(scope, arguments); 3442 3443 }; 3444 3445 }, 3446 3447 browser: (function() { 3448 3449 var ua = navigator.userAgent.toLowerCase(), res = {}, 3450 3451 match = /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) || 3452 3453 /(msie) ([\w.]+)/.exec(ua) || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || []; 3454 3455 res[match[1]] = true; 3456 3457 res.version = match[2] || "0"; 3458 3459 res.safariMac = ua.indexOf('mac') != -1 && ua.indexOf('safari') != -1; 3460 3461 return res; 3462 3463 })(), 3464 3465 getOffset: function (obj) { 3466 3467 if (obj.getBoundingClientRect && !jcf.isWinPhoneDevice) { 3468 3469 var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft; 3470 3471 var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; 3472 3473 var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0; 3474 3475 var clientTop = document.documentElement.clientTop || document.body.clientTop || 0; 3476 3477 return { 3478 3479 top:Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop), 3480 3481 left:Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft) 3482 3483 }; 3484 3485 } else { 3486 3487 var posLeft = 0, posTop = 0; 3488 3489 while (obj.offsetParent) {posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent;} 3490
3491 return {top:posTop,left:posLeft}; 3492 3493 } 3494 3495 }, 3496 3497 getScrollTop: function() { 3498 3499 return window.pageYOffset || document.documentElement.scrollTop; 3500 3501 }, 3502 3503 getScrollLeft: function() { 3504 3505 return window.pageXOffset || document.documentElement.scrollLeft; 3506 3507 }, 3508 3509 getWindowWidth: function(){ 3510 3511 return document.compatMode=='CSS1Compat' ? document.documentElement.clientWidth : document.body.clientWidth; 3512 3513 }, 3514 3515 getWindowHeight: function(){ 3516 3517 return document.compatMode=='CSS1Compat' ? document.documentElement.clientHeight : document.body.clientHeight; 3518 3519 }, 3520 3521 getStyle: function(el, prop) { 3522 3523 if (document.defaultView && document.defaultView.getComputedStyle) { 3524 3525 return document.defaultView.getComputedStyle(el, null)[prop]; 3526 3527 } else if (el.currentStyle) { 3528 3529 return el.currentStyle[prop]; 3530 3531 } else { 3532 3533 return el.style[prop]; 3534 3535 } 3536 3537 }, 3538 3539 getParent: function(obj, selector) { 3540 3541 while(obj.parentNode && obj.parentNode != document.body) { 3542 3543 if(obj.parentNode.tagName.toLowerCase() == selector.toLowerCase()) { 3544 3545 return obj.parentNode; 3546 3547 } 3548 3549 obj = obj.parentNode; 3550 3551 } 3552 3553 return false; 3554 3555 }, 3556 3557 isParent: function(parent, child) { 3558 3559 while(child.parentNode) { 3560 3561 if(child.parentNode === parent) { 3562 3563 return true; 3564 3565 } 3566 3567 child = child.parentNode; 3568 3569 } 3570 3571 return false; 3572 3573 }, 3574 3575 getLabelFor: function(object) { 3576 3577 var parentLabel = jcf.lib.getParent(object,'label'); 3578 3579 if(parentLabel) { 3580 3581 return parentLabel; 3582 3583 } else if(object.id) { 3584 3585 return jcf.lib.queryBySelector('label[for="' + object.id + '"]')[0]; 3586 3587 } 3588 3589 }, 3590 3591 disableTextSelection: function(el){ 3592 3593 if (typeof el.onselectstart !== 'undefined') { 3594 3595 el.onselectstart = function() {return false;}; 3596 3597 } else if(window.opera) { 3598 3599 el.setAttribute('unselectable', 'on'); 3600 3601 } else { 3602 3603 jcf.lib.addClass(el, jcf.baseOptions.unselectableClass); 3604 3605 } 3606 3607 }, 3608 3609 enableTextSelection: function(el) { 3610 3611 if (typeof el.onselectstart !== 'undefined') { 3612 3613 el.onselectstart = null; 3614 3615 } else if(window.opera) { 3616 3617 el.removeAttribute('unselectable'); 3618 3619 } else { 3620 3621 jcf.lib.removeClass(el, jcf.baseOptions.unselectableClass); 3622 3623 } 3624 3625 }, 3626 3627 queryBySelector: function(selector, scope){ 3628 3629 if(typeof scope === 'string') { 3630 3631 var result = []; 3632 3633 var holders = this.getElementsBySelector(scope); 3634 3635 for (var i = 0, contextNodes; i < holders.length; i++) { 3636 3637 contextNodes = Array.prototype.slice.call(this.getElementsBySelector(selector, holders[i])); 3638 3639 result = result.concat(contextNodes); 3640 3641 } 3642 3643 return result; 3644 3645 } else { 3646 3647 return this.getElementsBySelector(selector, scope); 3648 3649 } 3650 3651 }, 3652 3653 prevSibling: function(node) { 3654 3655 while(node = node.previousSibling) if(node.nodeType == 1) break; 3656 3657 return node; 3658 3659 }, 3660 3661 nextSibling: function(node) { 3662 3663 while(node = node.nextSibling) if(node.nodeType == 1) break; 3664 3665 return node; 3666 3667 }, 3668 3669 fireEvent: function(element,event) { 3670 3671 if(element.dispatchEvent){ 3672 3673 var evt = document.createEvent('HTMLEvents'); 3674 3675 evt.initEvent(event, true, true ); 3676 3677 return !element.dispatchEvent(evt); 3678 3679 }else if(document.createEventObject){ 3680 3681 var evt = document.createEventObject(); 3682 3683 return element.fireEvent('on'+event,evt); 3684 3685 } 3686 3687 }, 3688 3689 inherit: function(Child, Parent) { 3690 3691 var F = function() { } 3692 3693 F.prototype = Parent.prototype 3694 3695 Child.prototype = new F() 3696 3697 Child.prototype.constructor = Child 3698 3699 Child.superclass = Parent.prototype 3700 3701 }, 3702 3703 extend: function(obj) { 3704 3705 for(var i = 1; i < arguments.length; i++) { 3706 3707 for(var p in arguments[i]) { 3708 3709 if(arguments[i].hasOwnProperty(p)) { 3710 3711 obj[p] = arguments[i][p]; 3712 3713 } 3714 3715 } 3716 3717 } 3718 3719 return obj; 3720 3721 }, 3722 3723 hasClass: function (obj,cname) { 3724 3725 return (obj.className ? obj.className.match(new RegExp('(\\s|^)'+cname+'(\\s|$)')) : false); 3726 3727 }, 3728 3729 addClass: function (obj,cname) { 3730 3731 if (!this.hasClass(obj,cname)) obj.className += (!obj.className.length || obj.className.charAt(obj.className.length - 1) === ' ' ? '' : ' ') + cname; 3732 3733 }, 3734 3735 removeClass: function (obj,cname) { 3736 3737 if (this.hasClass(obj,cname)) obj.className=obj.className.replace(new RegExp('(\\s|^)'+cname+'(\\s|$)'),' ').replace(/\s+$/, ''); 3738 3739 }, 3740 3741 toggleClass: function(obj, cname, condition) { 3742 3743 if(condition) this.addClass(obj, cname); else this.removeClass(obj, cname); 3744 3745 }, 3746 3747 createElement: function(tagName, options) { 3748 3749 var el = document.createElement(tagName); 3750 3751 for(var p in options) { 3752 3753 if(options.hasOwnProperty(p)) { 3754 3755 switch (p) { 3756 3757 case 'class': el.className = options[p]; break; 3758 3759 case 'html': el.innerHTML = options[p]; break; 3760 3761 case 'style': this.setStyles(el, options[p]); break; 3762 3763 default: el.setAttribute(p, options[p]); 3764 3765 } 3766 3767 } 3768 3769 } 3770 3771 return el; 3772 3773 }, 3774 3775 setStyles: function(el, styles) { 3776 3777 for(var p in styles) { 3778 3779 if(styles.hasOwnProperty(p)) { 3780 3781 switch (p) { 3782 3783 case 'float': el.style.cssFloat = styles[p]; break; 3784 3785 case 'opacity': el.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+styles[p]*100+')'; el.style.opacity = styles[p]; break; 3786 3787 default: el.style[p] = (typeof styles[p] === 'undefined' ? 0 : styles[p]) + (typeof styles[p] === 'number' ? 'px' : ''); 3788 3789 } 3790 3791 } 3792 3793 } 3794 3795 return el; 3796 3797 }, 3798 3799 getInnerWidth: function(el) { 3800 3801 return el.offsetWidth - (parseInt(this.getStyle(el,'paddingLeft')) || 0) - (parseInt(this.getStyle(el,'paddingRight')) || 0); 3802 3803 }, 3804 3805 getInnerHeight: function(el) { 3806 3807 return el.offsetHeight - (parseInt(this.getStyle(el,'paddingTop')) || 0) - (parseInt(this.getStyle(el,'paddingBottom')) || 0); 3808 3809 }, 3810 3811 getAllClasses: function(cname, prefix, skip) { 3812 3813 if(!skip) skip = ''; 3814 3815 if(!prefix) prefix = ''; 3816 3817 return cname ? cname.replace(new RegExp('(\\s|^)'+skip+'(\\s|$)'),' ').replace(/[\s]*([\S]+)+[\s]*/gi,prefix+"$1 ") : ''; 3818 3819 }, 3820 3821 getElementsBySelector: function(selector, scope) { 3822 3823 if(typeof document.querySelectorAll === 'function') { 3824 3825 return (scope || document).querySelectorAll(selector); 3826 3827 } 3828 3829 var selectors = selector.split(','); 3830 3831 var resultList = []; 3832 3833 for(var s = 0; s < selectors.length; s++) { 3834 3835 var currentContext = [scope || document]; 3836 3837 var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' '); 3838 3839 for (var i = 0; i < tokens.length; i++) { 3840 3841 token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,''); 3842 3843 if (token.indexOf('#') > -1) { 3844 3845 var bits = token.split('#'), tagName = bits[0], id = bits[1]; 3846 3847 var element = document.getElementById(id); 3848 3849 if (tagName && element.nodeName.toLowerCase() != tagName) { 3850 3851 return []; 3852 3853 } 3854 3855 currentContext = [element]; 3856 3857 continue; 3858 3859 } 3860 3861 if (token.indexOf('.') > -1) { 3862 3863 var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0; 3864 3865 for (var h = 0; h < currentContext.length; h++) { 3866 3867 var elements; 3868 3869 if (tagName == '*') { 3870 3871 elements = currentContext[h].getElementsByTagName('*'); 3872 3873 } else { 3874 3875 elements = currentContext[h].getElementsByTagName(tagName); 3876 3877 } 3878 3879 for (var j = 0; j < elements.length; j++) { 3880 3881 found[foundCount++] = elements[j]; 3882 3883 } 3884 3885 } 3886 3887 currentContext = []; 3888 3889 var currentContextIndex = 0; 3890 3891 for (var k = 0; k < found.length; k++) { 3892 3893 if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) { 3894 3895 currentContext[currentContextIndex++] = found[k]; 3896 3897 } 3898 3899 } 3900 3901 continue; 3902 3903 } 3904 3905 if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^"]*)"?\]$/)) { 3906 3907 var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4; 3908 3909 if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) { 3910 3911 attrName = 'htmlFor'; 3912 3913 } 3914 3915 var found = [], foundCount = 0; 3916 3917 for (var h = 0; h < currentContext.length; h++) { 3918 3919 var elements; 3920 3921 if (tagName == '*') { 3922 3923 elements = currentContext[h].getElementsByTagName('*'); 3924 3925 } else { 3926 3927 elements = currentContext[h].getElementsByTagName(tagName); 3928 3929 } 3930 3931 for (var j = 0; elements[j]; j++) { 3932 3933 found[foundCount++] = elements[j]; 3934 3935 } 3936 3937 } 3938 3939 currentContext = []; 3940 3941 var currentContextIndex = 0, checkFunction; 3942 3943 switch (attrOperator) { 3944 3945 case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break; 3946 3947 case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break; 3948 3949 case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break; 3950 3951 case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break; 3952 3953 case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break; 3954 3955 case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break; 3956 3957 default : checkFunction = function(e) { return e.getAttribute(attrName) }; 3958 3959 } 3960 3961 currentContext = []; 3962 3963 var currentContextIndex = 0; 3964 3965 for (var k = 0; k < found.length; k++) { 3966 3967 if (checkFunction(found[k])) { 3968 3969 currentContext[currentContextIndex++] = found[k]; 3970 3971 } 3972 3973 } 3974 3975 continue; 3976 3977 } 3978 3979 tagName = token; 3980 3981 var found = [], foundCount = 0; 3982 3983 for (var h = 0; h < currentContext.length; h++) { 3984 3985 var elements = currentContext[h].getElementsByTagName(tagName); 3986 3987 for (var j = 0; j < elements.length; j++) { 3988 3989 found[foundCount++] = elements[j]; 3990 3991 } 3992 3993 } 3994 3995 currentContext = found; 3996 3997 } 3998 3999 resultList = [].concat(resultList,currentContext); 4000 4001 } 4002 4003 return resultList; 4004 4005 }, 4006 4007 scrollSize: (function(){ 4008 4009 var content, hold, sizeBefore, sizeAfter; 4010 4011 function buildSizer(){ 4012 4013 if(hold) removeSizer(); 4014 4015 content = document.createElement('div'); 4016 4017 hold = document.createElement('div'); 4018 4019 hold.style.cssText = 'position:absolute;overflow:hidden;width:100px;height:100px'; 4020 4021 hold.appendChild(content); 4022 4023 document.body.appendChild(hold); 4024 4025 } 4026 4027 function removeSizer(){ 4028 4029 document.body.removeChild(hold); 4030 4031 hold = null; 4032 4033 } 4034 4035 function calcSize(vertical) { 4036 4037 buildSizer(); 4038 4039 content.style.cssText = 'height:'+(vertical ? '100%' : '200px'); 4040 4041 sizeBefore = (vertical ? content.offsetHeight : content.offsetWidth); 4042 4043 hold.style.overflow = 'scroll'; content.innerHTML = 1; 4044 4045 sizeAfter = (vertical ? content.offsetHeight : content.offsetWidth); 4046 4047 if(vertical && hold.clientHeight) sizeAfter = hold.clientHeight; 4048 4049 removeSizer(); 4050 4051 return sizeBefore - sizeAfter; 4052 4053 } 4054 4055 return { 4056 4057 getWidth:function(){ 4058 4059 return calcSize(false); 4060 4061 }, 4062 4063 getHeight:function(){ 4064 4065 return calcSize(true) 4066 4067 } 4068 4069 } 4070 4071 }()), 4072 4073 domReady: function (handler){ 4074 4075 var called = false 4076 4077 function ready() { 4078 4079 if (called) return; 4080 4081 called = true; 4082 4083 handler(); 4084 4085 } 4086 4087 if (document.addEventListener) { 4088 4089 document.addEventListener("DOMContentLoaded", ready, false); 4090 4091 } else if (document.attachEvent) { 4092 4093 if (document.documentElement.doScroll && window == window.top) { 4094 4095 function tryScroll(){ 4096 4097 if (called) return 4098 4099 if (!document.body) return 4100 4101 try { 4102 4103 document.documentElement.doScroll("left") 4104 4105 ready() 4106 4107 } catch(e) { 4108 4109 setTimeout(tryScroll, 0) 4110 4111 } 4112 4113 } 4114 4115 tryScroll() 4116 4117 } 4118 4119 document.attachEvent("onreadystatechange", function(){ 4120 4121 if (document.readyState === "complete") { 4122 4123 ready() 4124 4125 } 4126 4127 }) 4128 4129 } 4130 4131 if (window.addEventListener) window.addEventListener('load', ready, false) 4132 4133 else if (window.attachEvent) window.attachEvent('onload', ready) 4134 4135 }, 4136 4137 event: (function(){ 4138 4139 var guid = 0; 4140 4141 function fixEvent(e) { 4142 4143 e = e || window.event; 4144 4145 if (e.isFixed) { 4146 4147 return e; 4148 4149 } 4150 4151 e.isFixed = true; 4152 4153 e.preventDefault = e.preventDefault || function(){this.returnValue = false} 4154 4155 e.stopPropagation = e.stopPropagation || function(){this.cancelBubble = true} 4156 4157 if (!e.target) { 4158 4159 e.target = e.srcElement 4160 4161 } 4162 4163 if (!e.relatedTarget && e.fromElement) { 4164 4165 e.relatedTarget = e.fromElement == e.target ? e.toElement : e.fromElement; 4166 4167 } 4168 4169 if (e.pageX == null && e.clientX != null) { 4170 4171 var html = document.documentElement, body = document.body; 4172 4173 e.pageX = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0); 4174 4175 e.pageY = e.clientY + (html && html.scrollTop || body && body.scrollTop || 0) - (html.clientTop || 0); 4176 4177 } 4178 4179 if (!e.which && e.button) { 4180 4181 e.which = e.button & 1 ? 1 : (e.button & 2 ? 3 : (e.button & 4 ? 2 : 0)); 4182 4183 } 4184 4185 if(e.type === "DOMMouseScroll" || e.type === 'mousewheel') { 4186 4187 e.mWheelDelta = 0; 4188 4189 if (e.wheelDelta) { 4190 4191 e.mWheelDelta = e.wheelDelta/120; 4192 4193 } else if (e.detail) { 4194 4195 e.mWheelDelta = -e.detail/3; 4196 4197 } 4198 4199 } 4200 4201 return e; 4202 4203 } 4204 4205 function commonHandle(event, customScope) { 4206 4207 event = fixEvent(event); 4208 4209 var handlers = this.events[event.type]; 4210 4211 for (var g in handlers) { 4212 4213 var handler = handlers[g]; 4214 4215 var ret = handler.call(customScope || this, event); 4216 4217 if (ret === false) { 4218 4219 event.preventDefault() 4220 4221 event.stopPropagation() 4222 4223 } 4224 4225 } 4226 4227 } 4228 4229 var publicAPI = { 4230 4231 add: function(elem, type, handler, forcedScope) { 4232 4233 // handle multiple events 4234 4235 if(type.indexOf(' ') > -1) { 4236 4237 var eventList = type.split(' '); 4238 4239 for(var i = 0; i < eventList.length; i++) { 4240 4241 publicAPI.add(elem, eventList[i], handler, forcedScope); 4242 4243 } 4244 4245 return; 4246 4247 } 4248 4249 4250 4251 if (elem.setInterval && (elem != window && !elem.frameElement)) { 4252 4253 elem = window; 4254 4255 } 4256 4257 if (!handler.guid) { 4258 4259 handler.guid = ++guid; 4260 4261 } 4262 4263 if (!elem.events) { 4264 4265 elem.events = {}; 4266 4267 elem.handle = function(event) { 4268 4269 return commonHandle.call(elem, event); 4270 4271 } 4272 4273 } 4274 4275 if (!elem.events[type]) { 4276 4277 elem.events[type] = {}; 4278 4279 if (elem.addEventListener) elem.addEventListener(type, elem.handle, false); 4280 4281 else if (elem.attachEvent) elem.attachEvent("on" + type, elem.handle); 4282 4283 if(type === 'mousewheel') { 4284 4285 publicAPI.add(elem, 'DOMMouseScroll', handler, forcedScope); 4286 4287 } 4288 4289 } 4290 4291 var fakeHandler = jcf.lib.bind(handler, forcedScope); 4292 4293 fakeHandler.guid = handler.guid; 4294 4295 elem.events[type][handler.guid] = forcedScope ? fakeHandler : handler; 4296 4297 }, 4298 4299 remove: function(elem, type, handler) { 4300 4301 // handle multiple events 4302 4303 if(type.indexOf(' ') > -1) { 4304 4305 var eventList = type.split(' '); 4306 4307 for(var i = 0; i < eventList.length; i++) { 4308 4309 publicAPI.remove(elem, eventList[i], handler); 4310 4311 } 4312 4313 return; 4314 4315 } 4316 4317 4318 4319 var handlers = elem.events && elem.events[type]; 4320 4321 if (!handlers) return; 4322 4323 delete handlers[handler.guid]; 4324
4325 for(var any in handlers) return; 4326 4327 if (elem.removeEventListener) elem.removeEventListener(type, elem.handle, false); 4328 4329 else if (elem.detachEvent) elem.detachEvent("on" + type, elem.handle); 4330 4331 delete elem.events[type]; 4332 4333 for (var any in elem.events) return; 4334 4335 try { 4336 4337 delete elem.handle; 4338 4339 delete elem.events; 4340 4341 } catch(e) { 4342 4343 if(elem.removeAttribute) { 4344 4345 elem.removeAttribute("handle"); 4346 4347 elem.removeAttribute("events"); 4348 4349 } 4350 4351 } 4352 4353 if(type === 'mousewheel') { 4354 4355 publicAPI.remove(elem, 'DOMMouseScroll', handler); 4356 4357 } 4358 4359 } 4360 4361 } 4362 4363 return publicAPI; 4364 4365 }()) 4366 4367} 4368 4369 4370 4371// custom select module 4372 4373jcf.addModule({ 4374 4375 name:'select', 4376 4377 selector:'select', 4378 4379 defaultOptions: { 4380 4381 useNativeDropOnMobileDevices: true, 4382 4383 hideDropOnScroll: true, 4384 4385 showNativeDrop: false, 4386 4387 handleDropPosition: false, 4388 4389 selectDropPosition: 'bottom', // or 'top' 4390 4391 wrapperClass:'select-area', 4392 4393 focusClass:'select-focus', 4394 4395 dropActiveClass:'select-active', 4396 4397 selectedClass:'item-selected', 4398 4399 currentSelectedClass:'current-selected', 4400 4401 disabledClass:'select-disabled', 4402 4403 valueSelector:'span.center', 4404 4405 optGroupClass:'optgroup', 4406 4407 openerSelector:'a.select-opener', 4408 4409 selectStructure:'<span class="left"></span><span class="center"></span><a class="select-opener"></a>', 4410 4411 wrapperTag: 'span', 4412 4413 classPrefix:'select-', 4414 4415 dropMaxHeight: 300, 4416 4417 dropFlippedClass: 'select-options-flipped', 4418 4419 dropHiddenClass:'options-hidden', 4420 4421 dropScrollableClass:'options-overflow', 4422 4423 dropClass:'select-options', 4424 4425 dropClassPrefix:'drop-', 4426 4427 dropStructure:'<div class="drop-holder"><div class="drop-list"></div></div>', 4428 4429 dropSelector:'div.drop-list' 4430 4431 }, 4432 4433 checkElement: function(el){ 4434 4435 return (!el.size && !el.multiple); 4436 4437 }, 4438 4439 setupWrapper: function(){ 4440 4441 jcf.lib.addClass(this.fakeElement, this.options.wrapperClass); 4442 4443 this.realElement.parentNode.insertBefore(this.fakeElement, this.realElement.nextSibling); 4444 4445 this.fakeElement.innerHTML = this.options.selectStructure; 4446 4447 this.fakeElement.style.width = (this.realElement.offsetWidth > 0 ? this.realElement.offsetWidth + 'px' : 'auto'); 4448 4449 4450 4451 // show native drop if specified in options 4452 4453 if(this.options.useNativeDropOnMobileDevices && (jcf.isTouchDevice || jcf.isWinPhoneDevice)) { 4454 4455 this.options.showNativeDrop = true; 4456 4457 } 4458 4459 if(this.options.showNativeDrop) { 4460 4461 this.fakeElement.appendChild(this.realElement); 4462 4463 jcf.lib.removeClass(this.realElement, this.options.hiddenClass); 4464 4465 jcf.lib.setStyles(this.realElement, { 4466 4467 top:0, 4468 4469 left:0, 4470 4471 margin:0, 4472 4473 padding:0, 4474 4475 opacity:0, 4476 4477 border:'none', 4478 4479 position:'absolute', 4480 4481 width: jcf.lib.getInnerWidth(this.fakeElement) - 1, 4482 4483 height: jcf.lib.getInnerHeight(this.fakeElement) - 1 4484 4485 }); 4486 4487 jcf.lib.event.add(this.realElement, jcf.eventPress, function(){ 4488 4489 this.realElement.title = ''; 4490 4491 }, this) 4492 4493 } 4494 4495 4496 4497 // create select body 4498 4499 this.opener = jcf.lib.queryBySelector(this.options.openerSelector, this.fakeElement)[0]; 4500 4501 this.valueText = jcf.lib.queryBySelector(this.options.valueSelector, this.fakeElement)[0]; 4502 4503 jcf.lib.disableTextSelection(this.valueText); 4504 4505 this.opener.jcf = this; 4506 4507 4508 4509 if(!this.options.showNativeDrop) { 4510 4511 this.createDropdown(); 4512 4513 this.refreshState(); 4514 4515 this.onControlReady(this); 4516 4517 this.hideDropdown(); 4518 4519 } else { 4520 4521 this.refreshState(); 4522 4523 } 4524 4525 this.addEvents(); 4526 4527 }, 4528 4529 addEvents: function(){ 4530 4531 if(this.options.showNativeDrop) { 4532 4533 jcf.lib.event.add(this.realElement, 'click', this.onChange, this); 4534 4535 } else { 4536 4537 jcf.lib.event.add(this.fakeElement, 'click', this.toggleDropdown, this); 4538 4539 } 4540 4541 jcf.lib.event.add(this.realElement, 'change', this.onChange, this); 4542 4543 }, 4544 4545 onFakeClick: function() { 4546 4547 // do nothing (drop toggles by toggleDropdown method) 4548 4549 }, 4550 4551 onFocus: function(){ 4552 4553 jcf.modules[this.name].superclass.onFocus.apply(this, arguments); 4554 4555 if(!this.options.showNativeDrop) { 4556 4557 // Mac Safari Fix 4558 4559 if(jcf.lib.browser.safariMac) { 4560 4561 this.realElement.setAttribute('size','2'); 4562 4563 } 4564 4565 jcf.lib.event.add(this.realElement, 'keydown', this.onKeyDown, this); 4566 4567 if(jcf.activeControl && jcf.activeControl != this) { 4568 4569 jcf.activeControl.hideDropdown(); 4570 4571 jcf.activeControl = this; 4572 4573 } 4574 4575 } 4576 4577 }, 4578 4579 onBlur: function(){ 4580 4581 if(!this.options.showNativeDrop) { 4582 4583 // Mac Safari Fix 4584 4585 if(jcf.lib.browser.safariMac) { 4586 4587 this.realElement.removeAttribute('size'); 4588 4589 } 4590 4591 if(!this.isActiveDrop() || !this.isOverDrop()) { 4592 4593 jcf.modules[this.name].superclass.onBlur.apply(this); 4594 4595 if(jcf.activeControl === this) jcf.activeControl = null; 4596 4597 if(!jcf.isTouchDevice) { 4598 4599 this.hideDropdown(); 4600 4601 } 4602 4603 } 4604 4605 jcf.lib.event.remove(this.realElement, 'keydown', this.onKeyDown); 4606 4607 } else { 4608 4609 jcf.modules[this.name].superclass.onBlur.apply(this); 4610 4611 } 4612 4613 }, 4614 4615 onChange: function() { 4616 4617 this.refreshState(); 4618 4619 }, 4620 4621 onKeyDown: function(e){ 4622 4623 this.dropOpened = true; 4624 4625 jcf.tmpFlag = true; 4626 4627 setTimeout(function(){jcf.tmpFlag = false},100); 4628 4629 var context = this; 4630 4631 context.keyboardFix = true; 4632 4633 setTimeout(function(){ 4634 4635 context.refreshState(); 4636 4637 },10); 4638 4639 if(e.keyCode == 13) { 4640 4641 context.toggleDropdown.apply(context); 4642 4643 return false;
4644 4645 } 4646 4647 }, 4648 4649 onResizeWindow: function(e){ 4650 4651 if(this.isActiveDrop()) { 4652 4653 this.hideDropdown(); 4654 4655 } 4656 4657 }, 4658 4659 onScrollWindow: function(e){ 4660 4661 if(this.options.hideDropOnScroll) { 4662 4663 this.hideDropdown(); 4664 4665 } else if(this.isActiveDrop()) { 4666 4667 this.positionDropdown(); 4668 4669 } 4670 4671 }, 4672 4673 onOptionClick: function(e){ 4674 4675 var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li'); 4676 4677 if(opener && !jcf.lib.hasClass(opener, 'opt-disabled')) { 4678 4679 this.dropOpened = true; 4680 4681 this.realElement.selectedIndex = parseInt(opener.getAttribute('rel')); 4682 4683 if(jcf.isTouchDevice) { 4684 4685 this.onFocus(); 4686 4687 } else { 4688 4689 this.realElement.focus(); 4690 4691 } 4692 4693 this.refreshState(); 4694 4695 this.hideDropdown(); 4696 4697 jcf.lib.fireEvent(this.realElement, 'change'); 4698 4699 } 4700 4701 return false; 4702 4703 }, 4704 4705 onClickOutside: function(e){ 4706 4707 if(jcf.tmpFlag) { 4708 4709 jcf.tmpFlag = false; 4710 4711 return; 4712 4713 } 4714 4715 if(!jcf.lib.isParent(this.fakeElement, e.target) && !jcf.lib.isParent(this.selectDrop, e.target)) { 4716 4717 this.hideDropdown(); 4718 4719 } 4720 4721 }, 4722 4723 onDropHover: function(e){ 4724 4725 if(!this.keyboardFix) { 4726 4727 this.hoverFlag = true; 4728 4729 var opener = e.target && e.target.tagName && e.target.tagName.toLowerCase() == 'li' ? e.target : jcf.lib.getParent(e.target, 'li'); 4730 4731 if(opener) { 4732 4733 this.realElement.selectedIndex = parseInt(opener.getAttribute('rel')); 4734 4735 this.refreshSelectedClass(parseInt(opener.getAttribute('rel'))); 4736 4737 } 4738 4739 } else { 4740 4741 this.keyboardFix = false; 4742 4743 } 4744 4745 }, 4746 4747 onDropLeave: function(){ 4748 4749 this.hoverFlag = false; 4750 4751 }, 4752 4753 isActiveDrop: function(){ 4754 4755 return !jcf.lib.hasClass(this.selectDrop, this.options.dropHiddenClass); 4756 4757 }, 4758 4759 isOverDrop: function(){ 4760 4761 return this.hoverFlag; 4762 4763 }, 4764 4765 createDropdown: function(){ 4766 4767 // remove old dropdown if exists 4768 4769 if(this.selectDrop && this.selectDrop.parentNode) { 4770 4771 this.selectDrop.parentNode.removeChild(this.selectDrop); 4772 4773 } 4774 4775 4776 4777 // create dropdown holder 4778 4779 this.selectDrop = document.createElement('div'); 4780 4781 this.selectDrop.className = this.options.dropClass; 4782 4783 this.selectDrop.innerHTML = this.options.dropStructure; 4784 4785 jcf.lib.setStyles(this.selectDrop, {position:'absolute'}); 4786 4787 this.selectList = jcf.lib.queryBySelector(this.options.dropSelector,this.selectDrop)[0]; 4788 4789 jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass); 4790 4791 document.body.appendChild(this.selectDrop); 4792 4793 this.selectDrop.jcf = this; 4794 4795 jcf.lib.event.add(this.selectDrop, 'click', this.onOptionClick, this); 4796 4797 jcf.lib.event.add(this.selectDrop, 'mouseover', this.onDropHover, this); 4798 4799 jcf.lib.event.add(this.selectDrop, 'mouseout', this.onDropLeave, this); 4800 4801 this.buildDropdown(); 4802 4803 }, 4804 4805 buildDropdown: function() { 4806 4807 // build select options / optgroups 4808 4809 this.buildDropdownOptions(); 4810 4811 4812 4813 // position and resize dropdown 4814 4815 this.positionDropdown(); 4816 4817 4818 4819 // cut dropdown if height exceedes 4820 4821 this.buildDropdownScroll(); 4822 4823 }, 4824 4825 buildDropdownOptions: function() { 4826 4827 this.resStructure = ''; 4828 4829 this.optNum = 0; 4830 4831 for(var i = 0; i < this.realElement.children.length; i++) { 4832 4833 this.resStructure += this.buildElement(this.realElement.children[i], i) +'\n'; 4834 4835 } 4836 4837 this.selectList.innerHTML = this.resStructure; 4838 4839 },
4840 4841 buildDropdownScroll: function() { 4842 4843 jcf.lib.addClass(this.selectDrop, jcf.lib.getAllClasses(this.realElement.className, this.options.dropClassPrefix, jcf.baseOptions.hiddenClass)); 4844 4845 if(this.options.dropMaxHeight) { 4846 4847 if(this.selectDrop.offsetHeight > this.options.dropMaxHeight) { 4848 4849 this.selectList.style.height = this.options.dropMaxHeight+'px'; 4850 4851 this.selectList.style.overflow = 'auto'; 4852 4853 this.selectList.style.overflowX = 'hidden'; 4854 4855 jcf.lib.addClass(this.selectDrop, this.options.dropScrollableClass); 4856 4857 } 4858 4859 } 4860 4861 }, 4862 4863 parseOptionTitle: function(optTitle) { 4864 4865 return (typeof optTitle === 'string' && /\.(jpg|gif|png|bmp|jpeg)(.*)?$/i.test(optTitle)) ? optTitle : ''; 4866 4867 }, 4868 4869 buildElement: function(obj, index){ 4870 4871 // build option 4872 4873 var res = '', optImage; 4874 4875 if(obj.tagName.toLowerCase() == 'option') { 4876 4877 if(!jcf.lib.prevSibling(obj) || jcf.lib.prevSibling(obj).tagName.toLowerCase() != 'option') { 4878 4879 res += '<ul>'; 4880 4881 } 4882 4883 4884 4885 optImage = this.parseOptionTitle(obj.title); 4886 4887 res += '<li rel="'+(this.optNum++)+'" class="'+(obj.className? obj.className + ' ' : '')+(obj.disabled? 'opt-disabled ' : '')+(index % 2 ? 'option-even ' : '')+'jcfcalc"><a href="#">'+(optImage ? '<img src="'+optImage+'" alt="" />' : '')+'<span>' + obj.innerHTML + '</span></a></li>'; 4888 4889 if(!jcf.lib.nextSibling(obj) || jcf.lib.nextSibling(obj).tagName.toLowerCase() != 'option') { 4890 4891 res += '</ul>'; 4892 4893 } 4894 4895 return res; 4896 4897 } 4898 4899 // build option group with options 4900 4901 else if(obj.tagName.toLowerCase() == 'optgroup' && obj.label) { 4902 4903 res += '<div class="'+this.options.optGroupClass+'">'; 4904 4905 res += '<strong class="jcfcalc"><em>'+(obj.label)+'</em></strong>'; 4906 4907 for(var i = 0; i < obj.children.length; i++) { 4908 4909 res += this.buildElement(obj.children[i], i); 4910 4911 } 4912 4913 res += '</div>'; 4914 4915 return res; 4916 4917 } 4918 4919 }, 4920 4921 positionDropdown: function(){ 4922 4923 var ofs = jcf.lib.getOffset(this.fakeElement), selectAreaHeight = this.fakeElement.offsetHeight, selectDropHeight = this.selectDrop.offsetHeight; 4924 4925 var fitInTop = ofs.top - selectDropHeight >= jcf.lib.getScrollTop() && jcf.lib.getScrollTop() + jcf.lib.getWindowHeight() < ofs.top + selectAreaHeight + selectDropHeight; 4926 4927 4928 4929 4930 4931 if((this.options.handleDropPosition && fitInTop) || this.options.selectDropPosition === 'top') { 4932 4933 this.selectDrop.style.top = (ofs.top - selectDropHeight)+'px'; 4934 4935 jcf.lib.addClass(this.selectDrop, this.options.dropFlippedClass); 4936 4937 jcf.lib.addClass(this.fakeElement, this.options.dropFlippedClass); 4938 4939 } else { 4940 4941 this.selectDrop.style.top = (ofs.top + selectAreaHeight)+'px'; 4942 4943 jcf.lib.removeClass(this.selectDrop, this.options.dropFlippedClass); 4944 4945 jcf.lib.removeClass(this.fakeElement, this.options.dropFlippedClass); 4946 4947 } 4948 4949 this.selectDrop.style.left = ofs.left+'px'; 4950 4951 this.selectDrop.style.width = this.fakeElement.offsetWidth+'px'; 4952 4953 },
4954 4955 showDropdown: function(){ 4956 4957 document.body.appendChild(this.selectDrop); 4958 4959 jcf.lib.removeClass(this.selectDrop, this.options.dropHiddenClass); 4960 4961 jcf.lib.addClass(this.fakeElement,this.options.dropActiveClass); 4962 4963 this.positionDropdown(); 4964 4965 4966 4967 // highlight current active item 4968 4969 var activeItem = this.getFakeActiveOption(); 4970 4971 this.removeClassFromItems(this.options.currentSelectedClass); 4972 4973 jcf.lib.addClass(activeItem, this.options.currentSelectedClass); 4974 4975 4976 4977 // show current dropdown 4978 4979 jcf.lib.event.add(window, 'resize', this.onResizeWindow, this); 4980 4981 jcf.lib.event.add(window, 'scroll', this.onScrollWindow, this); 4982 4983 jcf.lib.event.add(document, jcf.eventPress, this.onClickOutside, this); 4984 4985 this.positionDropdown(); 4986 4987 }, 4988 4989 hideDropdown: function(){ 4990 4991 if(this.selectDrop.parentNode) { 4992 4993 this.selectDrop.parentNode.removeChild(this.selectDrop); 4994 4995 } 4996 4997 if(typeof this.origSelectedIndex === 'number') { 4998 4999 this.realElement.selectedIndex = this.origSelectedIndex; 5000 5001 } 5002 5003 jcf.lib.removeClass(this.fakeElement,this.options.dropActiveClass); 5004 5005 jcf.lib.addClass(this.selectDrop, this.options.dropHiddenClass); 5006 5007 jcf.lib.event.remove(window, 'resize', this.onResizeWindow); 5008 5009 jcf.lib.event.remove(window, 'scroll', this.onScrollWindow); 5010 5011 jcf.lib.event.remove(document.documentElement, jcf.eventPress, this.onClickOutside); 5012 5013 if(jcf.isTouchDevice) { 5014 5015 this.onBlur(); 5016 5017 } 5018 5019 }, 5020 5021 toggleDropdown: function(){ 5022 5023 if(!this.realElement.disabled && this.realElement.options.length) { 5024 5025 if(jcf.isTouchDevice) { 5026 5027 this.onFocus(); 5028 5029 } else { 5030 5031 this.realElement.focus(); 5032 5033 } 5034 5035 if(this.isActiveDrop()) { 5036 5037 this.hideDropdown(); 5038 5039 } else { 5040 5041 this.showDropdown(); 5042 5043 } 5044 5045 this.refreshState(); 5046 5047 } 5048 5049 }, 5050 5051 scrollToItem: function(){ 5052 5053 if(this.isActiveDrop()) { 5054 5055 var dropHeight = this.selectList.offsetHeight; 5056 5057 var offsetTop = this.calcOptionOffset(this.getFakeActiveOption()); 5058 5059 var sTop = this.selectList.scrollTop; 5060 5061 var oHeight = this.getFakeActiveOption().offsetHeight; 5062 5063 //offsetTop+=sTop; 5064 5065 5066 5067 if(offsetTop >= sTop + dropHeight) { 5068 5069 this.selectList.scrollTop = offsetTop - dropHeight + oHeight; 5070 5071 } else if(offsetTop < sTop) { 5072 5073 this.selectList.scrollTop = offsetTop; 5074 5075 } 5076 5077 } 5078 5079 }, 5080 5081 getFakeActiveOption: function(c) { 5082 5083 return jcf.lib.queryBySelector('li[rel="'+(typeof c === 'number' ? c : this.realElement.selectedIndex) +'"]',this.selectList)[0]; 5084 5085 }, 5086 5087 calcOptionOffset: function(fake) { 5088 5089 var h = 0; 5090
5091 var els = jcf.lib.queryBySelector('.jcfcalc',this.selectList); 5092 5093 for(var i = 0; i < els.length; i++) { 5094 5095 if(els[i] == fake) break; 5096 5097 h+=els[i].offsetHeight; 5098 5099 } 5100 5101 return h; 5102 5103 }, 5104 5105 childrenHasItem: function(hold,item) { 5106 5107 var items = hold.getElementsByTagName('*'); 5108 5109 for(i = 0; i < items.length; i++) { 5110 5111 if(items[i] == item) return true; 5112 5113 } 5114 5115 return false; 5116 5117 }, 5118 5119 removeClassFromItems: function(className){ 5120 5121 var children = jcf.lib.queryBySelector('li',this.selectList); 5122 5123 for(var i = children.length - 1; i >= 0; i--) { 5124 5125 jcf.lib.removeClass(children[i], className); 5126 5127 } 5128 5129 }, 5130 5131 setSelectedClass: function(c){ 5132 5133 var activeOption = this.getFakeActiveOption(c); 5134 5135 if(activeOption) { 5136 5137 jcf.lib.addClass(activeOption, this.options.selectedClass); 5138 5139 } 5140 5141 }, 5142 5143 refreshSelectedClass: function(c){ 5144 5145 if(!this.options.showNativeDrop) { 5146 5147 this.removeClassFromItems(this.options.selectedClass); 5148 5149 this.setSelectedClass(c); 5150 5151 } 5152 5153 if(this.realElement.disabled) { 5154 5155 jcf.lib.addClass(this.fakeElement, this.options.disabledClass); 5156 5157 if(this.labelFor) { 5158 5159 jcf.lib.addClass(this.labelFor, this.options.labelDisabledClass); 5160 5161 } 5162 5163 } else { 5164 5165 jcf.lib.removeClass(this.fakeElement, this.options.disabledClass); 5166 5167 if(this.labelFor) { 5168 5169 jcf.lib.removeClass(this.labelFor, this.options.labelDisabledClass); 5170 5171 } 5172 5173 } 5174 5175 }, 5176 5177 refreshSelectedText: function() { 5178 5179 if(!this.dropOpened && this.realElement.title) { 5180 5181 this.valueText.innerHTML = this.realElement.title; 5182 5183 } else { 5184 5185 var activeOption = this.realElement.options[this.realElement.selectedIndex]; 5186 5187 if(activeOption) { 5188 5189 if(activeOption.title) { 5190 5191 var optImage = this.parseOptionTitle(this.realElement.options[this.realElement.selectedIndex].title); 5192 5193 this.valueText.innerHTML = (optImage ? '<img src="'+optImage+'" alt="" />' : '') + this.realElement.options[this.realElement.selectedIndex].innerHTML; 5194 5195 } else { 5196 5197 this.valueText.innerHTML = this.realElement.options[this.realElement.selectedIndex].innerHTML; 5198 5199 } 5200 5201 } 5202 5203 } 5204 5205 5206 5207 var selectedOption = this.realElement.options[this.realElement.selectedIndex]; 5208 5209 if(selectedOption && selectedOption.className) { 5210 5211 this.fakeElement.setAttribute('data-option-class', jcf.lib.getAllClasses(selectedOption.className, 'option-').replace(/^\s+|\s+$/g, '')); 5212 5213 } else { 5214 5215 this.fakeElement.removeAttribute('data-option-class'); 5216 5217 } 5218 5219 }, 5220 5221 refreshState: function(){ 5222 5223 this.origSelectedIndex = this.realElement.selectedIndex; 5224 5225 this.refreshSelectedClass(); 5226 5227 this.refreshSelectedText(); 5228 5229 if(!this.options.showNativeDrop) { 5230 5231 this.positionDropdown(); 5232 5233 if(this.selectDrop.offsetWidth) { 5234 5235 this.scrollToItem(); 5236 5237 } 5238 5239 } 5240 5241 } 5242 5243}); 5244 5245 5246 5247 5248 5249/*! Hammer.JS - v1.1.3 - 2014-05-20 5250 5251 * http://eightmedia.github.io/hammer.js 5252 5253 * 5254 5255 * Copyright (c) 2014 Jorik Tangelder <[email protected]>; 5256 5257 * Licensed under the MIT license */ 5258 5259!function(a,b){"use strict";function c(){d.READY||(s.determineEventTypes(),r.each(d.gestures,function(a){u.register(a)}),s.onTouch(d.DOCUMENT,n,u.detect),s.onTouch(d.DOCUMENT,o,u.detect),d.READY=!0)}var d=function v(a,b){return new v.Instance(a,b||{})};d.VERSION="1.1.3",d.defaults={behavior:{userSelect:"none",touchAction:"pan-y",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},d.DOCUMENT=document,d.HAS_POINTEREVENTS=navigator.pointerEnabled||navigator.msPointerEnabled,d.HAS_TOUCHEVENTS="ontouchstart"in a,d.IS_MOBILE=/mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent),d.NO_MOUSEEVENTS=d.HAS_TOUCHEVENTS&&d.IS_MOBILE||d.HAS_POINTEREVENTS,d.CALCULATE_INTERVAL=25;var e={},f=d.DIRECTION_DOWN="down",g=d.DIRECTION_LEFT="left",h=d.DIRECTION_UP="up",i=d.DIRECTION_RIGHT="right",j=d.POINTER_MOUSE="mouse",k=d.POINTER_TOUCH="touch",l=d.POINTER_PEN="pen",m=d.EVENT_START="start",n=d.EVENT_MOVE="move",o=d.EVENT_END="end",p=d.EVENT_RELEASE="release",q=d.EVENT_TOUCH="touch";d.READY=!1,d.plugins=d.plugins||{},d.gestures=d.gestures||{};var r=d.utils={extend:function(a,c,d){for(var e in c)!c.hasOwnProperty(e)||a[e]!==b&&d||(a[e]=c[e]);return a},on:function(a,b,c){a.addEventListener(b,c,!1)},off:function(a,b,c){a.removeEventListener(b,c,!1)},each:function(a,c,d){var e,f;
5259if("forEach"in a)a.forEach(c,d);else if(a.length!==b){for(e=0,f=a.length;f>e;e++)if(c.call(d,a[e],e,a)===!1)return}else for(e in a)if(a.hasOwnProperty(e)&&c.call(d,a[e],e,a)===!1)return},inStr:function(a,b){return a.indexOf(b)>-1},inArray:function(a,b){if(a.indexOf){var c=a.indexOf(b);return-1===c?!1:c}for(var d=0,e=a.length;e>d;d++)if(a[d]===b)return d;return!1},toArray:function(a){return Array.prototype.slice.call(a,0)},hasParent:function(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1},getCenter:function(a){var b=[],c=[],d=[],e=[],f=Math.min,g=Math.max;return 1===a.length?{pageX:a[0].pageX,pageY:a[0].pageY,clientX:a[0].clientX,clientY:a[0].clientY}:(r.each(a,function(a){b.push(a.pageX),c.push(a.pageY),d.push(a.clientX),e.push(a.clientY)}),{pageX:(f.apply(Math,b)+g.apply(Math,b))/2,pageY:(f.apply(Math,c)+g.apply(Math,c))/2,clientX:(f.apply(Math,d)+g.apply(Math,d))/2,clientY:(f.apply(Math,e)+g.apply(Math,e))/2})},getVelocity:function(a,b,c){return{x:Math.abs(b/a)||0,y:Math.abs(c/a)||0}},getAngle:function(a,b){var c=b.clientX-a.clientX,d=b.clientY-a.clientY;return 180*Math.atan2(d,c)/Math.PI},getDirection:function(a,b){var c=Math.abs(a.clientX-b.clientX),d=Math.abs(a.clientY-b.clientY);return c>=d?a.clientX-b.clientX>0?g:i:a.clientY-b.clientY>0?h:f},getDistance:function(a,b){var c=b.clientX-a.clientX,d=b.clientY-a.clientY;return Math.sqrt(c*c+d*d)},getScale:function(a,b){return a.length>=2&&b.length>=2?this.getDistance(b[0],b[1])/this.getDistance(a[0],a[1]):1},getRotation:function(a,b){return a.length>=2&&b.length>=2?this.getAngle(b[1],b[0])-this.getAngle(a[1],a[0]):0},isVertical:function(a){return a==h||a==f},setPrefixedCss:function(a,b,c,d){var e=["","Webkit","Moz","O","ms"];b=r.toCamelCase(b);for(var f=0;f<e.length;f++){var g=b;if(e[f]&&(g=e[f]+g.slice(0,1).toUpperCase()+g.slice(1)),g in a.style){a.style[g]=(null==d||d)&&c||"";break}}},toggleBehavior:function(a,b,c){if(b&&a&&a.style){r.each(b,function(b,d){r.setPrefixedCss(a,d,b,c)});var d=c&&function(){return!1};"none"==b.userSelect&&(a.onselectstart=d),"none"==b.userDrag&&(a.ondragstart=d)}},toCamelCase:function(a){return a.replace(/[_-]([a-z])/g,function(a){return a[1].toUpperCase()})}},s=d.event={preventMouseEvents:!1,started:!1,shouldDetect:!1,on:function(a,b,c,d){var e=b.split(" ");r.each(e,function(b){r.on(a,b,c),d&&d(b)})},off:function(a,b,c,d){var e=b.split(" ");r.each(e,function(b){r.off(a,b,c),d&&d(b)})},onTouch:function(a,b,c){var f=this,g=function(e){var g,h=e.type.toLowerCase(),i=d.HAS_POINTEREVENTS,j=r.inStr(h,"mouse");j&&f.preventMouseEvents||(j&&b==m&&0===e.button?(f.preventMouseEvents=!1,f.shouldDetect=!0):i&&b==m?f.shouldDetect=1===e.buttons||t.matchType(k,e):j||b!=m||(f.preventMouseEvents=!0,f.shouldDetect=!0),i&&b!=o&&t.updatePointer(b,e),f.shouldDetect&&(g=f.doDetect.call(f,e,b,a,c)),g==o&&(f.preventMouseEvents=!1,f.shouldDetect=!1,t.reset()),i&&b==o&&t.updatePointer(b,e))};return this.on(a,e[b],g),g},doDetect:function(a,b,c,d){var e=this.getTouchList(a,b),f=e.length,g=b,h=e.trigger,i=f;b==m?h=q:b==o&&(h=p,i=e.length-(a.changedTouches?a.changedTouches.length:1)),i>0&&this.started&&(g=n),this.started=!0;var j=this.collectEventData(c,g,e,a);return b!=o&&d.call(u,j),h&&(j.changedLength=i,j.eventType=h,d.call(u,j),j.eventType=g,delete j.changedLength),g==o&&(d.call(u,j),this.started=!1),g},determineEventTypes:function(){var b;return b=d.HAS_POINTEREVENTS?a.PointerEvent?["pointerdown","pointermove","pointerup pointercancel lostpointercapture"]:["MSPointerDown","MSPointerMove","MSPointerUp MSPointerCancel MSLostPointerCapture"]:d.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],e[m]=b[0],e[n]=b[1],e[o]=b[2],e},getTouchList:function(a,b){if(d.HAS_POINTEREVENTS&&!(navigator.msPointerEnabled&&!navigator.pointerEnabled))return t.getTouchList();if(a.touches){if(b==n)return a.touches;var c=[],e=[].concat(r.toArray(a.touches),r.toArray(a.changedTouches)),f=[];return r.each(e,function(a){r.inArray(c,a.identifier)===!1&&f.push(a),c.push(a.identifier)}),f}return a.identifier=1,[a]},collectEventData:function(a,b,c,d){var e=k;return r.inStr(d.type,"mouse")||t.matchType(j,d)?e=j:t.matchType(l,d)&&(e=l),{center:r.getCenter(c),timeStamp:Date.now(),target:d.target,touches:c,eventType:b,pointerType:e,srcEvent:d,preventDefault:function(){var a=this.srcEvent;a.preventManipulation&&a.preventManipulation(),a.preventDefault&&a.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return u.stopDetect()}}}},t=d.PointerEvent={pointers:{},getTouchList:function(){var a=[];return r.each(this.pointers,function(b){a.push(b)}),a},updatePointer:function(a,b){a==o||a!=o&&1!==b.buttons?delete this.pointers[b.pointerId]:(b.identifier=b.pointerId,this.pointers[b.pointerId]=b)},matchType:function(a,b){if(!b.pointerType)return!1;var c=b.pointerType,d={};return d[j]=c===(b.MSPOINTER_TYPE_MOUSE||j),d[k]=c===(b.MSPOINTER_TYPE_TOUCH||k),d[l]=c===(b.MSPOINTER_TYPE_PEN||l),d[a]},reset:function(){this.pointers={}}}
5259,u=d.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(a,b){this.current||(this.stopped=!1,this.current={inst:a,startEvent:r.extend({},b),lastEvent:!1,lastCalcEvent:!1,futureCalcEvent:!1,lastCalcData:{},name:""},this.detect(b))},detect:function(a){if(this.current&&!this.stopped){a=this.extendEventData(a);var b=this.current.inst,c=b.options;return r.each(this.gestures,function(d){!this.stopped&&b.enabled&&c[d.name]&&d.handler.call(d,a,b)},this),this.current&&(this.current.lastEvent=a),a.eventType==o&&this.stopDetect(),a}},stopDetect:function(){this.previous=r.extend({},this.current),this.current=null,this.stopped=!0},getCalculatedData:function(a,b,c,e,f){var g=this.current,h=!1,i=g.lastCalcEvent,j=g.lastCalcData;i&&a.timeStamp-i.timeStamp>d.CALCULATE_INTERVAL&&(b=i.center,c=a.timeStamp-i.timeStamp,e=a.center.clientX-i.center.clientX,f=a.center.clientY-i.center.clientY,h=!0),(a.eventType==q||a.eventType==p)&&(g.futureCalcEvent=a),(!g.lastCalcEvent||h)&&(j.velocity=r.getVelocity(c,e,f),j.angle=r.getAngle(b,a.center),j.direction=r.getDirection(b,a.center),g.lastCalcEvent=g.futureCalcEvent||a,g.futureCalcEvent=a),a.velocityX=j.velocity.x,a.velocityY=j.velocity.y,a.interimAngle=j.angle,a.interimDirection=j.direction},extendEventData:function(a){var b=this.current,c=b.startEvent,d=b.lastEvent||c;(a.eventType==q||a.eventType==p)&&(c.touches=[],r.each(a.touches,function(a){c.touches.push({clientX:a.clientX,clientY:a.clientY})}));var e=a.timeStamp-c.timeStamp,f=a.center.clientX-c.center.clientX,g=a.center.clientY-c.center.clientY;return this.getCalculatedData(a,d.center,e,f,g),r.extend(a,{startEvent:c,deltaTime:e,deltaX:f,deltaY:g,distance:r.getDistance(c.center,a.center),angle:r.getAngle(c.center,a.center),direction:r.getDirection(c.center,a.center),scale:r.getScale(c.touches,a.touches),rotation:r.getRotation(c.touches,a.touches)}),a},register:function(a){var c=a.defaults||{};return c[a.name]===b&&(c[a.name]=!0),r.extend(d.defaults,c,!0),a.index=a.index||1e3,this.gestures.push(a),this.gestures.sort(function(a,b){return a.index<b.index?-1:a.index>b.index?1:0}),this.gestures}};d.Instance=function(a,b){var e=this;c(),this.element=a,this.enabled=!0,r.each(b,function(a,c){delete b[c],b[r.toCamelCase(c)]=a}),this.options=r.extend(r.extend({},d.defaults),b||{}),this.options.behavior&&r.toggleBehavior(this.element,this.options.behavior,!0),this.eventStartHandler=s.onTouch(a,m,function(a){e.enabled&&a.eventType==m?u.startDetect(e,a):a.eventType==q&&u.detect(a)}),this.eventHandlers=[]},d.Instance.prototype={on:function(a,b){var c=this;return s.on(c.element,a,b,function(a){c.eventHandlers.push({gesture:a,handler:b})}),c},off:function(a,b){var c=this;return s.off(c.element,a,b,function(a){var d=r.inArray({gesture:a,handler:b});d!==!1&&c.eventHandlers.splice(d,1)}),c},trigger:function(a,b){b||(b={});var c=d.DOCUMENT.createEvent("Event");c.initEvent(a,!0,!0),c.gesture=b;var e=this.element;return r.hasParent(b.target,e)&&(e=b.target),e.dispatchEvent(c),this},enable:function(a){return this.enabled=a,this},dispose:function(){var a,b;for(r.toggleBehavior(this.element,this.options.behavior,!1),a=-1;b=this.eventHandlers[++a];)r.off(this.element,b.gesture,b.handler);return this.eventHandlers=[],s.off(this.element,e[m],this.eventStartHandler),null}},function(a){function b(b,d){var e=u.current;if(!(d.options.dragMaxTouches>0&&b.touches.length>d.options.dragMaxTouches))switch(b.eventType){case m:c=!1;break;case n:if(b.distance<d.options.dragMinDistance&&e.name!=a)return;var j=e.startEvent.center;if(e.name!=a&&(e.name=a,d.options.dragDistanceCorrection&&b.distance>0)){var k=Math.abs(d.options.dragMinDistance/b.distance);j.pageX+=b.deltaX*k,j.pageY+=b.deltaY*k,j.clientX+=b.deltaX*k,j.clientY+=b.deltaY*k,b=u.extendEventData(b)}(e.lastEvent.dragLockToAxis||d.options.dragLockToAxis&&d.options.dragLockMinDistance<=b.distance)&&(b.dragLockToAxis=!0);var l=e.lastEvent.direction;b.dragLockToAxis&&l!==b.direction&&(b.direction=r.isVertical(l)?b.deltaY<0?h:f:b.deltaX<0?g:i),c||(d.trigger(a+"start",b),c=!0),d.trigger(a,b),d.trigger(a+b.direction,b);var q=r.isVertical(b.direction);(d.options.dragBlockVertical&&q||d.options.dragBlockHorizontal&&!q)&&b.preventDefault();break;case p:c&&b.changedLength<=d.options.dragMaxTouches&&(d.trigger(a+"end",b),c=!1);break;case o:c=!1}}var c=!1;d.gestures.Drag={name:a,index:50,handler:b,defaults:{dragMinDistance:10,dragDistanceCorrection:!0,dragMaxTouches:1,dragBlockHorizontal:!1,dragBlockVertical:!1,dragLockToAxis:!1,dragLockMinDistance:25}}}("drag"),d.gestures.Gesture={name:"gesture",index:1337,handler:function(a,b){b.trigger(this.name,a)}},function(a){function b(b,d){var e=d.options,f=u.current;switch(b.eventType){case m:clearTimeout(c),f.name=a,c=setTimeout(function(){f&&f.name==a&&d.trigger(a,b)},e.holdTimeout);break;case n:b.distance>e.holdThreshold&&clearTimeout(c);break;case p:clearTimeout(c)}}var c;d.gestures.Hold={name:a,index:10,defaults:{holdTimeout:500,holdThreshold:2},handler:b}}("hold"),d.gestures.Release={name:"release",index:1/0,handler:function(a,b){a.eventType==p&&b.trigger(this.name,a)}},d.gestures.Swipe={name:"swipe",index:40,defaults:{swipeMinTouches:1,swipeMaxTouches:1,swipeVelocityX:.6,swipeVelocityY:.6},handler:function(a,b){if(a.eventType==p){var c=a.touches.length,d=b.options;if(c<d.swipeMinTouches||c>d.swipeMaxTouches)return;(a.velocityX>d.swipeVelocityX||a.velocityY>d.swipeVelocityY)&&(b.trigger(this.name,a),b.trigger(this.name+a.direction,a))}}},function(a){function b(b,d){var e,f,g=d.options,h=u.current,i=u.previous;switch(b.eventType){case m:c=!1;break;case n:c=c||b.distance>g.tapMaxDistance;break;case o:!r.inStr(b.srcEvent.type,"cancel")&&b.deltaTime<g.tapMaxTime&&!c&&(e=i&&i.lastEvent&&b.timeStamp-i.lastEvent.timeStamp,f=!1,i&&i.name==a&&e&&e<g.doubleTapInterval&&b.distance<g.doubleTapDistance&&(d.trigger("doubletap",b),f=!0),(!f||g.tapAlways)&&(h.name=a,d.trigger(h.name,b)))}}var c=!1;d.gestures.Tap={name:a,index:100,handler:b,defaults:{tapMaxTime:250,tapMaxDistance:10,tapAlways:!0,doubleTapDistance:20,doubleTapInterval:300}}}("tap"),d.gestures.Touch={name:"touch",index:-1/0,defaults:{preventDefault:!1,preventMouse:!1},handler:function(a,b){return b.options.preventMouse&&a.pointerType==j?void a.stopDetect():(b.options.preventDefault&&a.preventDefault(),void(a.eventType==q&&b.trigger("touch",a)))}},function(a){function b(b,d){switch(b.eventType){case m:c=!1;break;case n:if(b.touches.length<2)return;var e=Math.abs(1-b.scale),f=Math.abs(b.rotation);if(e<d.options.transformMinScale&&f<d.options.transformMinRotation)return;u.current.name=a,c||(d.trigger(a+"start",b),c=!0),d.trigger(a,b),f>d.options.transformMinRotation&&d.trigger("rotate",b),e>d.options.transformMinScale&&(d.trigger("pinch",b),d.trigger("pinch"+(b.scale<1?"in":"out"),b));break;case p:c&&b.changedLength<2&&(d.trigger(a+"end",b),c=!1)}}var c=!1;d.gestures.Transform={name:a,index:45,defaults:{transformMinScale:.01,transformMinRotation:1},handler:b}}("transform"),"function"==typeof define&&define.amd?define(function(){return d}):"undefined"!=typeof module&&module.exports?module.exports=d:a.Hammer=d}(window); 5260 5261 5262 5263/*! 5264 5265* FitVids 1.0.3 5266 5267* 5268
5269* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com 5270 5271* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ 5272 5273* Released under the WTFPL license - http://sam.zoy.org/wtfpl/ 5274 5275* 5276 5277* Date: Thu Sept 01 18:00:00 2011 -0500 5278 5279*/ 5280 5281;(function(a){a.fn.fitVids=function(b){var c={customSelector:null};if(!document.getElementById("fit-vids-style")){var f=document.createElement("div"),d=document.getElementsByTagName("base")[0]||document.getElementsByTagName("script")[0],e="­<style>.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}</style>";f.className="fit-vids-style";f.id="fit-vids-style";f.style.display="none";f.innerHTML=e;d.parentNode.insertBefore(f,d)}if(b){a.extend(c,b)}return this.each(function(){var g=["iframe[src*='player.vimeo.com']","iframe[src*='youtube.com']","iframe[src*='youtube-nocookie.com']","iframe[src*='kickstarter.com'][src*='video.html']","object","embed"];if(c.customSelector){g.push(c.customSelector)}var h=a(this).find(g.join(","));h=h.not("object object");h.each(function(){var m=a(this);if(this.tagName.toLowerCase()==="embed"&&m.parent("object").length||m.parent(".fluid-width-video-wrapper").length){return}var i=(this.tagName.toLowerCase()==="object"||(m.attr("height")&&!isNaN(parseInt(m.attr("height"),10))))?parseInt(m.attr("height"),10):m.height(),j=!isNaN(parseInt(m.attr("width"),10))?parseInt(m.attr("width"),10):m.width(),k=i/j;if(!m.attr("id")){var l="fitvid"+Math.floor(Math.random()*999999);m.attr("id",l)}m.wrap('<div class="fluid-width-video-wrapper"></div>').parent(".fluid-width-video-wrapper").css("padding-top",(k*100)+"%");m.removeAttr("height").removeAttr("width")})})}})(window.jQuery||window.Zepto); 5282
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.