1var body, 2 debugMode = false, 3 windowWidth = 0, 4 windowHeight = 0, 5 desktopWidth = 1139, /* Desktop powyżej podanej wielkosci */ 6 tabletWidth = 639, /* Tablet powyżej podanej wielkoÅci */ 7 mobileSize, /* PrzedziaÅ poniżej tabletu, nie definiowany */ 8 devbar_pages = []; 9 10$(function () { 11 body = $('body'); 12 windowSize(); 13 $(window).bind('resize load', function () { 14 windowSize(); // musi byc przed debugView 15 debugView(); 16 stickyFooter(); 17 }); 18 19 labelLinkFix(); 20 stickyHeader(); 21 rwdMenuHandler(); 22 langsMenuHandler(); 23 initFooterNavSlider(); 24 initTooltips(); 25 initSelect2(); 26 initiCheck(); 27 footerToggleHandler(); 28 rwdMenuActions(); 29 initMovingElements(); 30 31 // Bind header top-box elements 32 $('.top-box-container').each(function () { 33 DelayedHoverHandler.add($(this), { 34 leaveDelay: 120, 35 }); 36 }); 37 38 DelayedHoverHandler.add($('#main-menu > ul > li'), { 39 enterDelay: 150, 40 leaveDelay: 200, 41 }); 42 43 // fillView(); 44 /* 45 initFancybox(); 46 initMatchHeight(); 47 initLazyLoad(); 48 menuHover(); 49 */ 50 51 initSavedProducts(); 52 53 ElementsMovingHandler.add({ 54 element: $('.footer-col-4'), 55 resolution: 1280, 56 from: { 57 element: $('.footer-cols'), 58 method: 'appendTo', 59 }, 60 to: { 61 element: $('.footer-col-3'), 62 method: 'appendTo', 63 } 64 }); 65 66 if ($('header .langs-menu').length) { 67 ElementsMovingHandler.add({ 68 element: $('header .langs-menu'), 69 resolution: 1140, 70 from: { 71 element: $('header'), 72 method: 'prependTo', 73 }, 74 to: { 75 element: $('header > .container'), 76 method: 'appendTo', 77 } 78 }); 79 } 80 81 /* Handle grayscale when hovering parent */ 82 $('.gray-hover').bind('hover', function () { 83 $(this).addBack().find('.gray-target, .grayscale').toggleClass('grayscale-off'); 84 }); 85 86 87 /* Handle lines animation when in viewport */ 88 $('.static-lines.static-lines-corner').uAnimate({ 89 timeout: 400, 90 }); 91 92 93 // $('.footer-col-1 img').uAnimate({ 94 // classToAdd: 'opacityToLeft', 95 // timeout: 0, 96 // }); 97 98 99 /* Initialize sliders */ 100 var fullsliders = []; 101 $('.section-fullslider').each(function (i, el) { 102 var fullslider = new Fullslider($(el)); 103 fullsliders.push(fullslider); 104 fullslider.init(); 105 }); 106 107 $('.page-col > .heading, .page-col .page-col-title').matchHeight({property: 'min-height'}); 108 109 /* Initialize product sliders */ 110 $('.productsSlider-container').not('.no-slider .productsSlider-container').each(function () { 111 var $this = $(this); 112 $this.find('.product-list').slick({ 113 infinite: true, 114 slidesToShow: 6, 115 slidesToScroll: 1, 116 fade: false, 117 autoplay: true, 118 autoplaySpeed: 5000, 119 dots: false, 120 arrows: true, 121 prevArrow: $this.find('.slider-prev'), 122 nextArrow: $this.find('.slider-next'), 123 waitForAnimate: false, 124 responsive: [ 125 { 126 breakpoint: 1281, 127 settings: { 128 slidesToShow: 5, 129 } 130 }, 131 { 132 breakpoint: 1025, 133 settings: { 134 slidesToShow: 4, 135 } 136 }, 137 { 138 breakpoint: 768, 139 settings: { 140 slidesToShow: 3, 141 } 142 }, 143 { 144 breakpoint: 580, 145 settings: { 146 slidesToShow: 2, 147 } 148 }, 149 { 150 breakpoint: 380, 151 settings: { 152 slidesToShow: 1, 153 } 154 }, 155 ] 156 }) 157 }); 158 159 /* Initialize article sliders */ 160 $('.articlesSlider-container').not('.no-slider .articlesSlider-container').each(function () { 161 var $this = $(this); 162 $this.find('.articlebox-list').slick({ 163 infinite: true, 164 slidesToShow: 4, 165 slidesToScroll: 1, 166 fade: false, 167 autoplay: true, 168 autoplaySpeed: 5000, 169 dots: false, 170 arrows: true, 171 prevArrow: $this.find('.slider-prev'), 172 nextArrow: $this.find('.slider-next'), 173 waitForAnimate: false, 174 responsive: [ 175 { 176 breakpoint: 1441, 177 settings: { 178 slidesToShow: 3 179 } 180 }, 181 { 182 breakpoint: 1140, 183 settings: { 184 slidesToShow: 2 185 } 186 }, 187 { 188 breakpoint: 640, 189 settings: { 190 slidesToShow: 1 191 } 192 } 193 ] 194 }); 195 }); 196 197 /* When hovering on product list with category tiles - add helper class */ 198 var $productLists = $('.product-list'); 199 if ($productLists.length) { 200 $('.product-list-category-item').bind('mouseenter', function () { 201 var $this = $(this); 202 var $list = $this.closest('.product-list'); 203 $list.addClass('hovering-category'); 204 }).bind('mouseleave', function () { 205 var $this = $(this); 206 var $list = $this.closest('.product-list'); 207 $list.removeClass('hovering-category'); 208 }); 209 } 210}); 211 212function initTooltips() { 213 // Init standard tooltips 214 $('.tooltipable').tooltip(); 215 216 // Init tooltips with title and text 217 // data-title="tytuÅ" 218 // data-text="lorem ipsum lorem ipsum lorem ipsum" 219 $('.tooltipable-badge').each(function () { 220 var $this = $(this), 221 content = ""; 222 if ($this.data('title')) { 223 content += '<div class="tooltip-title">' + $this.data('title') + '</div>'; 224 } 225 if ($this.data('text')) { 226 content += '<div class="tooltip-text">' + $this.data('text') + '</div>'; 227 } 228 if (content) { 229 content = '<div class="tooltip-content">' + content + '</div>'; 230 } 231 $this.tooltip({ 232 html: true, 233 placement: 'auto top', 234 title: content, 235 }); 236 }); 237} 238 239/** 240 * jQuery Fancybox 241 */ 242function initFancybox() { 243 try { 244 $('a.fancy').fancybox({}); 245 } 246 catch (err) { 247 console.log('Library jQuery Fancybox doesn`t exsist'); 248 } 249} 250 251/** 252 * jQuery iCheck 253 */ 254function initiCheck() { 255 try { 256 $('input[type="radio"], input[type="checkbox"]').iCheck({ 257 checkboxClass: 'icheckbox_minimal-custom', 258 radioClass: 'iradio_minimal-custom', 259 increaseArea: '20%' 260 }); 261 } 262 catch (err) { 263 console.log('Library jQuery iCheck doesn`t exsist'); 264 } 265} 266 267/** 268 * jQuery Select 2 269 */ 270function initSelect2() { 271 try { 272 $('.select2 select').each(function () { 273 var $this = $(this); 274 $this.select2({ 275 dropdownParent: $this.parent(), 276 minimumResultsForSearch: Infinity, 277 }); 278 }); 279 280 // Fancybox 281 // $('.savedProducts-select2 select').each(function() { 282 // var $this = $(this); 283 // $this.select2({ 284 // dropdownParent: $this.parent(), 285 // minimumResultsForSearch: Infinity, 286 // }); 287 // }); 288 } 289 catch (err) { 290 console.log('Library jQuery Select2 doesn`t exsist'); 291 } 292} 293 294/** 295 * jQuery MatchHeight 296 */ 297function initMatchHeight() { 298 try { 299 $('.match').matchHeight(); 300 } 301 catch (err) { 302 console.log('Library jQuery matchHeight doesn`t exsist'); 303 } 304} 305 306/** 307 * jQuery LazyLoad 308 */ 309function initLazyLoad() { 310 try { 311 $(".lazyload").lazyload({ 312 threshold: 200 313 }); 314 } 315 catch (err) { 316 console.log('Library jQuery lazyload doesn`t exsist'); 317 } 318} 319 320 321/** 322 * RWD menu 323 */ 324function rwdMenuHandler() { 325 var $header = $('header'); 326 var $rwdMenuWraper = $('.rwd-menu-wrapper'); 327 328 $(".nav-toggle").bind('click touch', function () { 329 $('.rwd-menu').css('padding-top', $('#container-page').offset().top); 330 $rwdMenuWraper.css('margin-top', $header.height()); 331 $rwdMenuWraper.css('padding-bottom', $header.height()); 332 333 if ($(this).hasClass('active')) { 334 rwdMenuHide(); 335 } else { 336 rwdMenuShow(); 337 } 338 return false;
339 }); 340} 341 342function rwdMenuShow() { 343 langsMenuHide(); 344 345 $(".nav-toggle").addClass('active'); 346 body.addClass('body-block'); 347 $('.rwd-menu').slideDown(); 348} 349 350function rwdMenuHide() { 351 $(".nav-toggle").removeClass('active'); 352 body.removeClass('body-block'); 353 if (windowWidth >= 1140) { 354 $('.rwd-menu').css('display', 'none'); 355 } else { 356 $('.rwd-menu').slideUp(); 357 } 358} 359 360/** 361 * Languages menu 362 */ 363function langsMenuHandler() { 364 $('.lang-button').bind('click touch', function () { 365 var $header = $('header'); 366 var $rwdLangWrapper = $('.rwd-lang-wrapper'); 367 368 $('.rwd-lang').css('padding-top', $('#container-page').offset().top); 369 $rwdLangWrapper.css('margin-top', $header.height()); 370 $rwdLangWrapper.css('padding-bottom', $header.height()); 371 372 if ($('.langs-menu').hasClass('active')) { 373 langsMenuHide(); 374 } else { 375 langsMenuShow(); 376 } 377 return false; 378 }); 379} 380 381function langsMenuShow() { 382 rwdMenuHide(); 383 384 $('.langs-menu').addClass('active'); 385 $('.langs-menu > ul').slideDown(); 386 $('.rwd-lang').slideDown(); 387 body.addClass('body-block'); 388} 389 390function langsMenuHide() { 391 $('.langs-menu').removeClass('active'); 392 $('.langs-menu > ul').slideUp(); 393 if (windowWidth >= 1140) { 394 $('.rwd-lang').css('display', 'none'); 395 } else { 396 $('.rwd-lang').slideUp(); 397 } 398 body.removeClass('body-block'); 399} 400 401function rwdMenuActions() { 402 $('.rwd-menu ul li a').bind('click touch', function () { 403 var $this = $(this), 404 li = $(this).closest('li'), 405 child = li.find('ul:first'); 406 407 if ($this.attr('href') != undefined) { 408 return true; 409 } 410 411 if (child.length) { 412 if (li.hasClass('active')) { 413 child.slideUp(); 414 li.removeClass('active'); 415 } else { 416 child.slideDown(); 417 li.addClass('active'); 418 } 419 return false; 420 } 421 }); 422 $('.rwd-menu ul li .pull-right').bind('click', function () { 423 var $this = $(this).parent(), 424 li = $(this).closest('li'), 425 child = li.find('ul:first'), 426 427 ul = $(this).closest('ul'); 428 429 ul.find('li.active').not(li).find('ul:first').slideUp('slow', function () { 430 $(this).parent().removeClass('active') 431 }); 432 433 434 if (child.length) { 435 if (li.hasClass('active')) { 436 child.slideUp(); 437 li.removeClass('active'); 438 } else { 439 child.slideDown(); 440 li.addClass('active'); 441 } 442 return false; 443 } 444 }); 445} 446 447/** 448 * Sticky footer 449 */ 450function stickyFooter() { 451 var $height = $("#container-page > footer").outerHeight(); 452 $("body.sticky-footer #page").css({ 453 marginBottom: -$height + "px", 454 paddingBottom: $height + "px" 455 }); 456} 457 458function fillView() { 459 var $fillview = $('.fillview'), 460 $header = $('header'), 461 $footer = $('footer'); 462 if ($fillview.length) { 463 $(window).bind('resize load', function () { 464 $fillview.css({ 465 'min-height': windowHeight - $header.outerHeight() - $footer.outerHeight(), 466 }); 467 }); 468 } 469} 470 471/** 472 * Przyklejenie menu do góry strony. 473 */ 474function stickyHeader() { 475 var fireAfterResize, 476 $fromTop = 0, 477 $underSlider = true, 478 $rwdRun = true; 479 480 $(window).bind('resize load', function () { 481 clearTimeout(fireAfterResize); 482 fireAfterResize = setTimeout(function () { 483 headerStickyBase($fromTop, $underSlider, $rwdRun); 484 }, 500); 485 }); 486 487 $(window).bind("scroll", function () { 488 headerStickyBase($fromTop, $underSlider, $rwdRun); 489 }); 490} 491 492/** 493 * Opóźnienie zamkniÄcia submenu nawigacji po zjechaniu myszkÄ 494 * Aby poprawnie użyÄ nalezy ostylowaÄ klasÄ "hovered" 495 */ 496function menuHover() { 497 var timeout; 498 499 $('#main-menu ul li') 500 .mouseenter(function () { 501 var $this = $(this); 502 var $submenu = $this.find('ul'); 503 if (!$submenu.length) return; 504 clearTimeout(timeout); 505 $('#main-menu ul li ul').removeClass('hovered'); 506 $submenu.addClass('hovered'); 507 }) 508 .mouseleave(function () { 509 var $this = $(this); 510 var $submenu = $this.find('ul'); 511 if (!$submenu.length) return; 512 timeout = setTimeout(function () { 513 $submenu.removeClass('hovered'); 514 }, 300); 515 }); 516} 517 518 519function labelLinkFix() { 520 $('label a').each(function () { 521 var $this = $(this), span; 522 $this.attr('target', '_blank'); 523 $this.attr('rel', 'noopener'); 524 525 span = $('<span onclick="event.stopPropagation();"></span>'); 526 span.html($(this).clone()); 527 $this.replaceWith(span); 528 }); 529} 530 531 532function initFooterNavSlider() { 533 // $('.footer-nav-slider .footer-nav-item').each(function(i, el) { 534 // var $this = $(el); 535 // $this.css('width', $this.outerWidth()); 536 // }); 537 // $('.footer-nav-slider').slick({ 538 // dots: false, 539 // arrows: true, 540 // infinite: false,
541 // speed: 800, 542 // centerMode: false, 543 // variableWidth: true 544 // }); 545} 546 547function initSavedProducts() { 548 $('.savedProducts-open').on('click touch', function (e) { 549 var $this = $(this), 550 productId = $this.data("id"), 551 materialId = []; 552 e.preventDefault(); 553 554 $.ajax({ 555 url: "/inquiry/add", 556 data: {ajax: 1, product_id: productId, materials: materialId}, 557 method: "POST", 558 success: function (resp) { 559 $("#savedProducts .productSmall-list").html(resp.content); 560 561 var $headerList = $('.headerlink-list'); 562 if ($headerList.hasClass('compact')) { 563 window.savedProductsOpenedBefore = true; 564 } else { 565 $headerList.addClass('compact'); 566 window.savedProductsOpenedBefore = false; 567 } 568 569 $.fancybox.open($('#savedProducts'), { 570 touch: false, 571 baseClass: "savedProducts-popup", 572 beforeShow: function () { 573 if (!window.savedProductsOpenedBefore) { 574 $('.headerlink .savedProducts-open').addClass('savedProducts-is-opened'); 575 } 576 }, 577 afterClose: function () { 578 $('.headerlink .savedProducts-open').removeClass('savedProducts-is-opened'); 579 window.savedProductsOpenedBefore = true; 580 } 581 }); 582 } 583 }); 584 585 e.preventDefault(); 586 return false; 587 }); 588 589 $('.savedProducts-close').on('click touch', function (e) { 590 $.fancybox.close(); 591 e.preventDefault(); 592 return false; 593 }); 594 595 $('.savedProducts-ask').on('click touch', function (e) { 596 var $this = $(this); 597 $this.closest('#savedProducts').find('.savedProducts-form').slideToggle(); 598 599 e.preventDefault(); 600 return false; 601 }); 602} 603 604/** 605 * Handles fullscreen realizations viewing - slider, next/prev relization, related products slider 606 * @param GROUP {String} - Name for a group of realizations that should be grouped together 607 * @constructor 608 * 609 * [Element that opens up popup should contain:] 610 * data-fsv-group="{String}" - Name of the realizations group 611 * href="{String}" - Unique ID of the target popup element 612 * 613 * [Element that contains the popup structure for given single realization should contain:] 614 * class="fsv-popup" 615 * data-fsv-group="{String}" - Name of the realizations group 616 * data-fsv-id="{String}" - Unique ID 617 */ 618function FullscreenViewer(GROUP) { 619 var that = this, 620 isOpened = false, 621 isPanelOpened = false, 622 $opened = $(); 623 624 if (typeof GROUP !== "string") { 625 console.error('FullscreenViewer constructor: argument "group" must not be empty and must be a string'); 626 return; 627 } 628 629 /* Bind elements that open up popup of given group's realization (ALSO BINDS FUTURE ELEMENTS) */ 630 body.on('click touch', '.fsv-open[data-fsv-group="' + GROUP + '"], [data-fsv-group="' + GROUP + '"] .fsv-open', onClickOpen); 631 632 /* Bind close buttons */ 633 body.on('click touch', '[data-fsv-group="' + GROUP + '"] .fsv-close', onClickClose); 634 635 /* Bind panel toggle buttons */ 636 body.on('click touch', '.fsv-popup[data-fsv-group="' + GROUP + '"] .fsv-panel-toggle', function () { 637 that.togglePanel($(this).closest('.fsv-popup')); 638 }); 639 body.on('touchmove', '.fsv-popup[data-fsv-group="' + GROUP + '"] .fsv-panel-bar', function () { 640 if (windowWidth < 1140) { 641 that.togglePanel($(this).closest('.fsv-popup')); 642 } 643 }); 644 645 $(document).bind('keydown', function (e) { 646 if (isOpened) { 647 //ESCAPE 648 if (e.which === 27) { 649 that.close(); 650 } 651 //ARROW UP 652 else if (e.which === 38) { 653 that.togglePanel($opened, true); 654 } 655 //ARROW DOWN 656 else if (e.which === 40) { 657 that.togglePanel($opened, false); 658 } 659 //ENTER / SPACE 660 else if (e.which === 13 || e.which === 32) { 661 that.togglePanel($opened); 662 } 663 //ARROW LEFT 664 else if (e.which === 37) { 665 if (isPanelOpened) { 666 $opened.find('.fsv-panel .product-list').slick('slickPrev'); 667 } else { 668 $opened.find('.fsv-slider').slick('slickPrev'); 669 } 670 } 671 //ARROW RIGHT 672 else if (e.which === 39) { 673 if (isPanelOpened) { 674 $opened.find('.fsv-panel .product-list').slick('slickNext'); 675 } else { 676 $opened.find('.fsv-slider').slick('slickNext'); 677 } 678 } 679 } 680 }); 681
682 function init() { 683 if (location.hash) { 684 openFromHash(); 685 } 686 } 687 688 /***************************************************************************************************************/ 689 /** 690 * Handles click on element that opens up FullscreenViewer 691 * @param e {Event} - Click event 692 */ 693 function onClickOpen(e) { 694 var $this = $(this), 695 targetId = $this.attr('href'); 696 697 if (!targetId) { 698 console.error('FullscreenViewer, onClickOpen(): Clicked element doesnt contain href!'); 699 return; 700 } 701 702 that.open(targetId); 703 704 e.preventDefault(); 705 return false; 706 } 707 708 /** 709 * Handles click on element that closes FullscreenViewer 710 * @param e {Event} - Click event 711 */ 712 function onClickClose(e) { 713 console.log('Closing'); 714 that.close(); 715 } 716 717 /** 718 * Opens viewer with realization of given id 719 * @param targetId {String} 720 */ 721 this.open = function (targetId) { 722 var $target = $('[data-fsv-id="' + targetId + '"]'); 723 724 if (!$target.length) { 725 /* 726 console.error('FullscreenViewer, open(): Cannot find target with data-fsv-id of', targetId); 727 return; 728 */ 729 730 var tab = targetId.split('#'); 731 getAjaxData(tab[0], tab[1]); 732 targetId = '#' + tab[1]; 733 $target = $('[data-fsv-id="' + targetId + '"]'); 734 } 735 736 this.close(); 737 738 location.hash = targetId; 739 740 $opened = $target; 741 742 // body.addClass('fsv-opened'); 743 744 initPopup($target); 745 746 $opened.addClass('active'); 747 748 isOpened = true; 749 }; 750 751 /** 752 * Closes this FullscreenViewer (if opened) 753 */ 754 this.close = function () { 755 $opened.removeClass('active'); 756 body.removeClass('fsv-opened'); 757 isOpened = false; 758 isPanelOpened = false; 759 $opened = $(); 760 location.hash = ""; 761 }; 762 763 /** 764 * Opens bottom panel in given popup 765 * @param {jQuery} $popup - $('.fsv-popup') 766 * @param {boolean} [forcedState] - force state instead od toggling 767 */ 768 this.togglePanel = function ($popup, forcedState) { 769 if (typeof forcedState === "boolean") { 770 if (forcedState) { 771 $popup.find('.fsv-panel').addClass('active'); 772 isPanelOpened = true; 773 } else { 774 $popup.find('.fsv-panel').removeClass('active'); 775 isPanelOpened = false; 776 } 777 } else { 778 $popup.find('.fsv-panel').toggleClass('active'); 779 isPanelOpened = !isPanelOpened; 780 } 781 }; 782 783 /** 784 * Initializes popup that hasn't been opened before 785 * Starts sliders etc 786 * @param $popup {jQuery} - $('.fsv-popup') 787 */ 788 function initPopup($popup) { 789 if ($popup.hasClass('initialized')) { 790 $popup.find('.fsv-slider').slick('slickGoTo', 0, true); 791 } else { 792 // Main slider 793 $popup.find('.fsv-slider').slick({ 794 infinite: false, 795 slidesToShow: 1, 796 slidesToScroll: 1, 797 fade: true, 798 autoplay: false, 799 autoplaySpeed: 6000, 800 speed: 1500, 801 dots: false, 802 arrows: true, 803 accesibility: false, 804 waitForAnimate: false, 805 }) 806 .on('init beforeChange reInit', function (event, slick, currentSlide, nextSlide) { 807 if (nextSlide === undefined) { 808 nextSlide = 0; 809 } 810 updateSliderIndicator($popup, nextSlide); 811 812 var totalSlides = getTotalSlides($popup); 813 var showPrevGoto = (nextSlide === 0); 814 var showNextGoto = (nextSlide === totalSlides - 1); 815 816 if (showPrevGoto || showNextGoto) { 817 updateGotos($popup, showPrevGoto, showNextGoto); 818 } else { 819 updateGotos($popup, false, false, true); 820 } 821 }); 822 823 updateSliderIndicator($popup, 0); 824 825 if (getTotalSlides($popup) <= 1) { 826 updateGotos($popup, true, true); 827 } else { 828 updateGotos($popup, true, false); 829 } 830 831 // Product slider 832 $popup.find('.product-list').slick({ 833 infinite: true, 834 slidesToShow: 6, 835 slidesToScroll: 1, 836 fade: false, 837 autoplay: false, 838 autoplaySpeed: 3000, 839 dots: false, 840 arrows: true, 841 prevArrow: $popup.find('.fsv-panel .productsSlider-container .slider-prev'), 842 nextArrow: $popup.find('.fsv-panel .productsSlider-container .slider-next'), 843 accesibility: false, 844 waitForAnimate: false, 845 responsive: [ 846 { 847 breakpoint: 1281, 848 settings: { 849 slidesToShow: 5, 850 } 851 }, 852 { 853 breakpoint: 901, 854 settings: { 855 slidesToShow: 4, 856 } 857 }, 858 { 859 breakpoint: 768, 860 settings: { 861 slidesToShow: 3, 862 } 863 }, 864 { 865 breakpoint: 560, 866 settings: { 867 slidesToShow: 2, 868 } 869 }, 870 ], 871 }); 872 873 $popup.addClass('initialized'); 874 } 875 } 876 877 function openFromHash() { 878 var $target = $('[data-fsv-id="' + location.hash + '"][data-fsv-group="' + GROUP + '"]'); 879 if ($target.length) { 880 that.open(location.hash); 881 } 882 } 883 884 /** 885 * Update slider's indicator based on given index of a slide 886 * Calculates its width and position 887 * @param $popup {jQuery} - $('.fsv-popup') 888 * @param index {number} - index of slide 889 */ 890 function updateSliderIndicator($popup, index) { 891 var totalSlides = getTotalSlides($popup); 892 $popup.find('.fsv-indicator > span').css({ 893 width: (100 / totalSlides) + "%", 894 left: (index / totalSlides * 100) + "%", 895 }); 896 } 897 898 /** 899 * Update prev/next realization squares based on .fsv-group-item order AN
899D/OR show/hide gotos 900 * .fsv-group-item class is used to figure out order of realizations 901 * @param {jQuery} $popup - $('.fsv-popup') 902 * @param {boolean} [showPrev] - optional flag for hiding/showing prev goto 903 * @param {boolean} [showNext] - optional flag for hiding/showing next goto 904 * @param {boolean} [dontUpdate] - optional flag for skipping update of gotos' content 905 */ 906 function updateGotos($popup, showPrev, showNext, dontUpdate) { 907 dontUpdate = true; 908 909 //Get all realization items 910 var $groupItems = $('.fsv-group-item[data-fsv-group="' + GROUP + '"]'); 911 //Get current realization ID 912 var id = $popup.data('fsv-id'); 913 //Find the index of current realization in items collection 914 var itemIndex = $groupItems.index('[href="' + id + '"]'); 915 //Get previous and next realization item 916 var $prev = $groupItems.eq(itemIndex - 1); 917 var $next = $groupItems.eq(itemIndex + 1); 918 919 if ($prev.is($groupItems.eq(itemIndex))) $prev = $(); 920 if ($next.is($groupItems.eq(itemIndex))) $next = $(); 921 922 var $gotoPrev = $popup.find('.fsv-goto-prev'); 923 var $gotoNext = $popup.find('.fsv-goto-next'); 924 925 var imgUrl; 926 927 if (!dontUpdate && $prev.length) { 928 imgUrl = $prev.find('img').attr('src'); 929 $gotoPrev.find('.fsv-goto-img').css({ 930 'background-image': 'url(' + imgUrl + ')', 931 }); 932 $gotoPrev.attr('href', $prev.attr('href')); 933 } 934 if (typeof showPrev === "boolean") { 935 if (showPrev && $prev.length) { 936 $gotoPrev.addClass('active'); 937 } else { 938 $gotoPrev.removeClass('active'); 939 } 940 } else if ($prev.length === 0) { 941 $gotoPrev.removeClass('active'); 942 } 943 944 if (!dontUpdate && $next.length) { 945 imgUrl = $next.find('img').attr('src'); 946 $gotoNext.find('.fsv-goto-img').css({ 947 'background-image': 'url(' + imgUrl + ')', 948 }); 949 $gotoNext.attr('href', $next.attr('href')); 950 } 951 if (typeof showNext === "boolean") { 952 if (showNext && $next.length) { 953 $gotoNext.addClass('active'); 954 } else { 955 $gotoNext.removeClass('active'); 956 } 957 } else if ($next.length === 0) { 958 $gotoNext.removeClass('active'); 959 } 960 } 961 962 /** 963 * Returns a total number of slides in the popup 964 * @param {jQuery} $popup - $('.fsv-popup') 965 * @returns {Number} 966 */ 967 function getTotalSlides($popup) { 968 return $popup.find('.fsv-slide').not('.slick-cloned').length; 969 } 970 971 /** 972 * Returns group of this FullscreenViewer 973 * @returns {string} 974 */ 975 this.getGroup = function () { 976 return GROUP; 977 }; 978 979 function getAjaxData(href, hash) { 980 if (popups.indexOf(hash) == -1) { 981 $.ajax({ 982 url: href, 983 data: {ajax: 1, popup: 1, slug: hash}, 984 method: "POST", 985 dataType: "json", 986 success: function (resp) { 987 $(".page-realizations").append(resp.content); 988 that.open('#' + hash); 989 popups.push(hash); 990 } 991 }); 992 } 993 } 994 995 init(); 996} 997 998function Fullslider($slidersection) { 999 if (typeof $slidersection !== "object") { 1000 console.error('Fullslider constructor: property $slidersection must be a jQuery element'); 1001 return; 1002 } 1003 if ($slidersection.length === 0) { 1004 console.error('Fullslider constructor: $slidersection must not be empty'); 1005 return; 1006 } 1007 if ($slidersection.length > 1) { 1008 console.error('Fullslider constructor: $slidersection must contain only ONE element'); 1009 return; 1010 } 1011 1012 var that = this; 1013 1014 this.$element = $slidersection; 1015 var $bar = this.$element.find('.fullslider-bar'); 1016 this.$indicator = $slidersection.find('.fullslider-indicator > span'); 1017 this.slideCount = $slidersection.find('.fullslider-slide').length; 1018 1019 this.init = function () { 1020 var $that = this; 1021 $slidersection.find('.fullslider-slide').each(function () { 1022 var $this = $(this), 1023 href = $this.data('href'); 1024 1025 if (href) { 1026 $this.bind('click touch', function () { 1027 if ($bar.find('.fullslider-btn').length) { 1028 $bar.find('.fullslider-btn')[0].click(); 1029 } 1030 }); 1031 } 1032 }); 1033 1034 $slidersection.find('.fullslider').slick({ 1035 infinite: true, 1036 slidesToShow: 1, 1037 slidesToScroll: 1, 1038 fade: true, 1039 autoplay: true, 1040 autoplaySpeed: 5000, 1041 speed: 1600, 1042 dots: false, 1043 arrows: true, 1044 waitForAnimate: false, 1045 }) 1046 .on('init beforeChange reInit', function (event, slick, currentSlide, nextSlide) { 1047 if (nextSlide === undefined) { 1048 nextSlide = 0; 1049 } 1050 that.updateIndicator(nextSlide); 1051 that.updateBarData(nextSlide); 1052 }); 1053 1054 this.updateBarData(0); 1055 this.updateIndicator(0); 1056 1057 $slidersection.data('scrollTo', false); 1058 $slidersection.find('.slick-arrow').bind('click touch', function () { 1059 if (windowWidth >= 1140) { 1060 if ($slidersection.data('scrollTo') == true) return; 1061 $slidersection.data('scrollTo', true); 1062 $(window).scrollTo($slidersection, { 1063 duration: 400, 1064 onAfter: function () { 1065 $slidersection.data('scrollTo', false); 1066 } 1067 }); 1068 } 1069 }); 1070 1071 $slidersection.find('.fullslider-content .content-wrapper').bind('mouseenter', function () { 1072 if (windowWidth >= 1140) { 1073 $bar.addClass('hovered'); 1074 } 1075 }).bind('mouseleave', function () { 1076 if (windowWidth >= 1140) { 1077 $bar.removeClass('hovered'); 1078 } 1079 }); 1080 }; 1081 1082 this.updateIndicator = function (nextSlide) { 1083 that.$indicator.css({
1084 width: (100 / that.slideCount) + "%", 1085 left: (nextSlide / that.slideCount * 100) + "%", 1086 }); 1087 }; 1088 1089 this.updateBarData = function (nextSlide) { 1090 var $btn = $slidersection.find('.fullslider-slide[data-slideid="' + nextSlide + '"]').eq(0).find('.fullslider-bar-data').clone(); 1091 var $leftBar = $slidersection.find('.fullslider-bar-left'); 1092 $leftBar.empty(); 1093 if ($btn.length) { 1094 $leftBar.append($btn); 1095 } 1096 }; 1097} 1098 1099/** 1100 * Handles text numeric animation 1101 * @param $elements - {jQuery} elements to animate text 1102 * data-value="float" - {"float", default: integer} Number type, can be float (21.37), defaults to integer 1103 * data-value-type="" - {number} value to animate to 1104 * data-timeout="600" - {number - miliseconds} of lag before animation start 1105 * data-duration="3000" - {number - miliseconds} of animation length 1106 * data-value-prefix="Value: " - {string} to put before each number in animation 1107 * data-value-suffix=" PLN" - {string} to put after each number in animation 1108 * @param options - extra options 1109 * { 1110 * callback - {function} to call on animation finish 1111 * } 1112 */ 1113function animateCountUp($elements, options) { 1114 if (typeof options !== 'object') options = {}; 1115 1116 function animateCount($element) { 1117 var value, 1118 $this = $element, 1119 type = $this.attr('data-value-type'), 1120 value_prefix = $this.attr('data-value-prefix'), 1121 value_suffix = $this.attr('data-value-suffix'), 1122 timeout = Number($this.attr('data-timeout')), 1123 duration = Number($this.attr('data-duration')); 1124 1125 if (isNaN(Number($this.attr('data-value')))) { 1126 console.warn('CountUp: element with class "countup" must have a data-value attribute with a number value'); 1127 return; 1128 } 1129 1130 // DEFAULTS 1131 timeout = isNaN(timeout) ? 0 : timeout; 1132 duration = isNaN(duration) ? 2500 : duration; 1133 1134 if (value_prefix) { 1135 value_prefix = value_prefix + " "; 1136 } else { 1137 value_prefix = ""; 1138 } 1139 if (value_suffix) { 1140 value_suffix = " " + value_suffix; 1141 } else { 1142 value_suffix = ""; 1143 } 1144 1145 setTimeout(function () { 1146 if (type === "float") { 1147 value = parseFloat($this.attr('data-value'), 10); 1148 $({countNum: 0.00}).animate( 1149 {countNum: value}, 1150 { 1151 duration: duration, 1152 easing: 'swing', 1153 step: function () { 1154 $this.text(value_prefix + this.countNum.toLocaleString(undefined, { 1155 minimumFractionDigits: 2, 1156 maximumFractionDigits: 2 1157 }) + value_suffix); 1158 }, 1159 complete: function () { 1160 $this.text(value_prefix + this.countNum.toLocaleString(undefined, { 1161 minimumFractionDigits: 2, 1162 maximumFractionDigits: 2 1163 }) + value_suffix); 1164 if (typeof options.callback === 'function') { 1165 options.callback(); 1166 } 1167 $this.addClass('countup-ended'); 1168 } 1169 } 1170 ); 1171 } else { 1172 value = parseInt($this.attr('data-value'), 10); 1173 $({countNum: 0}).animate( 1174 {countNum: value}, 1175 { 1176 duration: duration, 1177 easing: 'swing', 1178 step: function () { 1179 $this.text(value_prefix + Math.round(this.countNum) + value_suffix); 1180 }, 1181 complete: function () { 1182 $this.text(value_prefix + this.countNum + value_suffix); 1183 if (typeof options.callback === 'function') { 1184 options.callback(); 1185 } 1186 $this.addClass('countup-ended'); 1187 } 1188 } 1189 ); 1190 } 1191 $this.addClass('countup-started'); 1192 }, timeout); 1193 } 1194 1195 $elements.each(function () { 1196 var $this = $(this);
1197 var delay = parseInt($this.attr('data-delay')); 1198 delay = isNaN(delay) ? 0 : delay; 1199 setTimeout(function () { 1200 animateCount($this); 1201 }, delay); 1202 }); 1203} 1204 1205 1206/** 1207 * Initializes a horizontally scrollable map 1208 * @param $el - container with all necessary elements 1209 * @param options 1210 * @constructor 1211 */ 1212function ImageMap($el, options) { 1213 var that = this; 1214 if (typeof options !== 'object') options = {}; 1215 1216 var $inside = $el.find('.imageMap-inside'), 1217 $viewport = $el.find('.imageMap-viewport'), 1218 $view = $el.find('.imageMap-view'), 1219 $arrowLeft = $el.find('.imageMap-arrow-left'), 1220 $arrowRight = $el.find('.imageMap-arrow-right'); 1221 1222 if ($viewport.length === 0) { 1223 console.error('ImageMap: cannot find viewport'); 1224 return; 1225 } 1226 if ($view.length === 0) { 1227 console.error('ImageMap: cannot find view'); 1228 return; 1229 } 1230 1231 /** 1232 * Bind mouse events for dragging 1233 */ 1234 var drag, startx, diffx, dragTimeout; 1235 $viewport.bind({ 1236 'mousedown': function (e) { 1237 if (e.which !== 1) return; 1238 if (!e) { 1239 e = window.event; 1240 } 1241 if (e.target && e.target.className === 'imageMap-area') { 1242 e.preventDefault(); 1243 return false; 1244 } 1245 startx = e.clientX + $viewport[0].scrollLeft; 1246 diffx = 0; 1247 drag = true; 1248 }, 1249 'mouseup mouseleave': function (e) { 1250 if (!e) { 1251 e = window.event; 1252 } 1253 drag = false; 1254 }, 1255 'mousemove': function (e) { 1256 if (drag === true) { 1257 if (!e) { 1258 e = window.event; 1259 } 1260 diffx = (startx - (e.clientX + $viewport[0].scrollLeft)); 1261 $viewport[0].scrollLeft += diffx; 1262 clearTimeout(dragTimeout); 1263 dragTimeout = setTimeout(that.updateOverflowing, 100) 1264 } 1265 }, 1266 }); 1267 1268 /** 1269 * Bind window changes for updating 1270 */ 1271 var viewportScrollWidth, viewportWidth, viewportScrollMax; 1272 $(window).bind('resize load', function () { 1273 that.update(); 1274 }); 1275 1276 /** 1277 * Arrows functionality - scrolling animation 1278 */ 1279 var FPS = 60, // How fast {frames per second} 1280 SCROLL_SPEED = 10; // How much {pixels} per frame 1281 /** Do NOT change : **/ 1282 var fpsInterval = 1000 / FPS, 1283 scrollAnimationRight, scrollAnimationLeft, 1284 animLeftStart, animLeftThen, 1285 animRightStart, animRightThen; 1286 /** ************* **/ 1287 $arrowLeft.bind({ 1288 'mousedown': function (e) { 1289 if (e.which !== 1) return; 1290 animRightThen = Date.now(); 1291 animRightStart = animRightThen; 1292 requestAnimationFrame(scrollToRight); 1293 scrollAnimationRight = true; 1294 }, 1295 'mouseup mouseleave': function () { 1296 scrollAnimationRight = false; 1297 }, 1298 }); 1299 $arrowRight.bind({ 1300 'mousedown': function (e) { 1301 if (e.which !== 1) return; 1302 animLeftThen = Date.now(); 1303 animLeftStart = animLeftThen; 1304 requestAnimationFrame(scrollToLeft); 1305 scrollAnimationLeft = true; 1306 }, 1307 'mouseup mouseleave': function () { 1308 scrollAnimationLeft = false; 1309 }, 1310 }); 1311 1312 // Scroll left animation loop 1313 function scrollToLeft() { 1314 if (!scrollAnimationLeft) return; 1315 1316 var now = Date.now(), 1317 elapsed = now - animLeftThen; 1318 1319 // FPS lock 1320 if (elapsed > fpsInterval) { 1321 that.incScroll(SCROLL_SPEED); 1322 } 1323 1324 requestAnimationFrame(scrollToLeft); 1325 } 1326 1327 // Scroll right animation loop 1328 function scrollToRight() { 1329 if (!scrollAnimationRight) return; 1330 1331 var now = Date.now(), 1332 elapsed = now - animRightThen; 1333 1334 // FPS lock 1335 if (elapsed > fpsInterval) { 1336 that.incScroll(-SCROLL_SPEED); 1337 } 1338 1339 requestAnimationFrame(scrollToRight); 1340 } 1341 1342 /** 1343 * Bind mouse hover to pause autoplay 1344 */ 1345 var autoplayRequest, 1346 autoplayThen = Date.now(), 1347 autoplay = true, 1348 autoplayPerFrame = 1, 1349 autoplayDirection = 1; // -1/1 1350 $inside.bind({ 1351 'mouseenter': function () { 1352 console.dir(1); 1353 autoplay = false;
1354 stopAutoplay(); 1355 }, 1356 'mouseleave': function () { 1357 console.dir(2); 1358 stopAutoplay(); 1359 autoplay = true; 1360 doAutoplay() 1361 }, 1362 }); 1363 1364 function doAutoplay() { 1365 if (!autoplay) return; 1366 1367 var now = Date.now(), 1368 elapsed = now - autoplayThen, 1369 upToAnEdge = false; 1370 1371 // FPS lock 1372 if (elapsed > fpsInterval * 2) { 1373 upToAnEdge = that.incScroll(autoplayDirection * autoplayPerFrame); 1374 console.dir(upToAnEdge); 1375 autoplayThen = Date.now(); 1376 } 1377 1378 if (upToAnEdge) autoplayDirection *= -1; 1379 1380 autoplayRequest = requestAnimationFrame(doAutoplay); 1381 } 1382 1383 function stopAutoplay() { 1384 console.dir('stop'); 1385 autoplay = false; 1386 cancelAnimationFrame(autoplayRequest); 1387 } 1388 1389 /** 1390 * Updates 1391 */ 1392 this.update = function () { 1393 that.updateOverflowing(); 1394 }; 1395 1396 /** 1397 * Updates classes that determine whether map is overflowing on the left or/and right 1398 * Returns boolean - whenever any edge is not overflowing = true 1399 */ 1400 var overflowLeft = false, 1401 overflowRight = false; 1402 this.updateOverflowing = function () { 1403 var result = false;
1404 1405 viewportScrollWidth = $viewport[0].scrollWidth; 1406 viewportWidth = $viewport.outerWidth(); 1407 viewportScrollMax = viewportScrollWidth - viewportWidth; 1408 1409 if ($viewport.scrollLeft() > 0) { 1410 $el.addClass('imageMap--overflowLeft'); 1411 overflowLeft = true; 1412 } else if ($viewport.scrollLeft() === 0) { 1413 $el.removeClass('imageMap--overflowLeft'); 1414 overflowLeft = false; 1415 result = true; 1416 } 1417 1418 if ($viewport.scrollLeft() < viewportScrollMax) { 1419 $el.addClass('imageMap--overflowRight'); 1420 overflowRight = true; 1421 } else if ($viewport.scrollLeft() === viewportScrollMax) { 1422 $el.removeClass('imageMap--overflowRight'); 1423 overflowRight = false; 1424 result = true; 1425 } 1426 1427 return result; 1428 }; 1429 1430 /** 1431 * Scroll by this much pixels 1432 * @param px {number} 1433 */ 1434 this.incScroll = function (px) { 1435 $viewport.scrollLeft($viewport.scrollLeft() + px); 1436 return that.updateOverflowing(); 1437 }; 1438 /** 1439 * Set scroll to this position 1440 * @param px {number} 1441 */ 1442 this.setScroll = function (px) { 1443 $viewport.scrollLeft(px); 1444 return that.updateOverflowing(); 1445 }; 1446 1447 /** 1448 * Set scroll based on mousemove event 1449 * @param e {Event} 1450 */ 1451 this.setScrollByEvent = function (e) { 1452 // Show dragging cursor 1453 if (!isCursorScroll) { 1454 $viewport.css('cursor', 'e-resize'); 1455 isCursorScroll = true; 1456 } 1457 var x = parseInt(e.clientX) - parseInt($view[0].getBoundingClientRect().left); 1458 1459 var diff = lastX - x; 1460 1461 $viewport[0].scrollLeft = $viewport[0].scrollLeft + diff; 1462 1463 lastX = x; 1464 1465 that.updateOverflowing(); 1466 }; 1467 1468 /** 1469 * Set starting scroll position 1470 */ 1471 if (options.startingOffset) this.setScroll(options.startingOffset); 1472} 1473 1474var AffixHandler = { 1475 _binds: [], 1476 _initialized: false, 1477 /** 1478 * Add affix to keep track of 1479 * @param $target {jQuery} - element to affix 1480 * @param $column {jQuery} - container element as a track for affixed element 1481 * @param rwdBreakpoint {number} - OPTIONAL - stop affixing on and below this breakpoint 1482 * @returns {boolean} 1483 */ 1484 add: function ($target, $column, rwdBreakpoint, callback) { 1485 // Inner vars 1486 var affixState = 0; 1487 1488 //Validation 1489 if (!($target instanceof jQuery)) { 1490 console.error('AffixController: required parameter "$target" must be a jQuery object: ', $target); 1491 return false; 1492 } 1493 if ($target.length !== 1) { 1494 console.error('AffixController: required parameter "$target" must be a jQuery set of only ONE element: ', $target); 1495 return false; 1496 } 1497 if (!($column instanceof jQuery)) { 1498 console.error('AffixController: required parameter "$column" must be a jQuery object: ', $column); 1499 return false; 1500 } 1501 if ($column.length !== 1) { 1502 console.error('AffixController: required parameter "$column" must be a jQuery set of only ONE element: ', $column); 1503 return false; 1504 } 1505 if (rwdBreakpoint !== undefined && rwdBreakpoint !== null) { 1506 if (typeof rwdBreakpoint !== 'number') { 1507 console.error('AffixController: optional parameter "rwdBreakpoint" must be a number: ', rwdBreakpoint); 1508 return false; 1509 } 1510 } else { 1511 rwdBreakpoint = 0; 1512 } 1513 if (callback !== undefined && callback !== null) { 1514 if (typeof callback !== 'function') { 1515 console.error('AffixController: optional parameter "callback" must be a function: ', callback); 1516 return false; 1517 } 1518 } else { 1519 callback = null; 1520 } 1521 1522 //Push to binds 1523 this._binds.push({ 1524 $target: $target, 1525 $column: $column, 1526 rwdBreakpoint: rwdBreakpoint, 1527 //Internal state: 1528 affixState: 0, 1529 callback: callback, 1530 }); 1531 1532 //Initialize handler 1533 this._initialize(); 1534 1535 return true; 1536 }, 1537 _initialize: function () { 1538 if (!this._initialized) { 1539 //Utility vars 1540 var $window = $(window), 1541 that = this; 1542 1543 $(window).on('load resize scroll', function () { 1544 for (var i = 0; i < that._binds.length; i++) { 1545 var current = that._binds[i], 1546 $this = current.$target, 1547 $column = current.$column, 1548 rwdBreakpoint = current.rwdBreakpoint, 1549 callback = current.callback; 1550 1551 $this.css('width', $column.outerWidth()); 1552 $this.css('width', $column.width()); 1553 1554 //var $height = $this.outerHeight(); 1555 //$column.css('min-height', $height); 1556 1557 if (windowWidth <= rwdBreakpoint) { 1558 $this.removeClass('affix affix-top affix-bottom'); 1559 return; 1560 } 1561 1562 // var windowTopOffset = parseInt(windowHeight / 2 - $this.outerHeight() / 2); 1563 var windowTopOffset = $('header').outerHeight() + 15; 1564 1565 if ($window.scrollTop() > ($column.offset().top - windowTopOffset)) { 1566 // If overflows bottom 1567 if ($column.offset().top + $column.outerHeight() < windowTopOffset + $this.outerHeight() + $window.scrollTop()) { 1568 if (current.affixState === 1) return; 1569 current.affixState = 1; 1570 $this.removeClass('affix-top affix').addClass('affix-bottom'); 1571 $this.css('top', ''); 1572 } 1573 // If in the middle 1574 else { 1575 if (current.affixState !== 2) { 1576 $this.removeClass('affix-top affix-bottom').addClass('affix'); 1577 } 1578 current.affixState = 2; 1579 $this.css('top', windowTopOffset); 1580 } 1581 } 1582 // If overflows top 1583 else { 1584 if (current.affixState === 3) return; 1585 current.affixState = 3; 1586 $this.removeClass('affix-bottom affix').addClass('affix-top'); 1587 $this.css('top', ''); 1588 } 1589 1590 if (callback) { 1591 (callback.bind($this))(); 1592 } 1593 } 1594 }); 1595 this._initialized = true; 1596 } 1597 }, 1598}; 1599 1600/** 1601 * Usage example: 1602 DelayedHoverHandler.add($('#main-menu li'), { 1603 enterDelay: 300, 1604 leaveDelay: 100, 1605 enterCallback: function () {}, 1606 leaveCallback: function () {}, 1607 }); 1608 1609 * Adds .hovered class on hovered targets 1610 * Can set delay for hover and unhover 1611 * 1612 * options { 1613 * [BASIC:] 1614 * enterDelay {number} - miliseconds to delay hover 1615 * leaveDelay {number} - miliseconds to delay unhover 1616 * 1617 * [EXTRA:] 1618 * keepHover {boolean} - doesn't remove hover - does only move it to a different hovered sibling 1619 * instantHoverSwitch {boolean} - ignores enterDelay and leaveDelay when already initialized on one of the elements and user starts to hover different element 1620 * true - leaveDelay doesn't work, enterDelay works only for first hovered element and then works instantly for next ones 1621 * false - always use provided delays for entering and leaving 1622 * 1623 * [CALLBACKS:] 1624 * enterCallback - call provided function on hover (jQuery element is binded as 'this') 1625 * leaveCallback - call provided function on unhover (jQuery element is binded as 'this') 1626 * } 1627 */ 1628var DelayedHoverHandler = { 1629 // Do NOT change (use options instead): 1630 Defaults: { 1631 ENTER_DELAY: 0, // ms 1632 LEAVE_DELAY: 0, // ms 1633 KEEP_HOVER: false, 1634 INSTANT_HOVER_SWITCH: false, 1635 }, 1636 add: function ($targets, options) { 1637 if (!($targets instanceof jQuery)) { 1638 console.error('DelayedHoverHandler: required parameter "$targets" must be a jQuery object: ', $targets); 1639 return false;
1640 } 1641 if (typeof options !== "undefined") { 1642 if (typeof options !== "object") { 1643 console.error('DelayedHoverHandler: optional parameter "options" must be an object: ', options); 1644 return false; 1645 } 1646 if (options.hasOwnProperty('enterCallback') && typeof options['enterCallback'] !== 'function') { 1647 console.error('DelayedHoverHandler: optional option "enterCallback" must be a function: ', options['enterCallback']); 1648 return false; 1649 } 1650 if (options.hasOwnProperty('leaveCallback') && typeof options['leaveCallback'] !== 'function') { 1651 console.error('DelayedHoverHandler: optional option "leaveCallback" must be a function: ', options['leaveCallback']); 1652 return false; 1653 } 1654 } 1655 1656 var enterDelay = this.Defaults.ENTER_DELAY, 1657 leaveDelay = this.Defaults.LEAVE_DELAY, 1658 keepHover = this.Defaults.KEEP_HOVER, 1659 instantHoverSwitch = this.Defaults.INSTANT_HOVER_SWITCH; 1660 1661 if (options) { 1662 if (options.hasOwnProperty('enterDelay') && !isNaN(options['enterDelay'])) { 1663 enterDelay = parseInt(options.enterDelay); 1664 } 1665 if (options.hasOwnProperty('leaveDelay') && !isNaN(options['leaveDelay'])) { 1666 leaveDelay = parseInt(options.leaveDelay); 1667 } 1668 if (options.hasOwnProperty('keepHover')) { 1669 keepHover = options.keepHover; 1670 } 1671 if (options.hasOwnProperty('instantHoverSwitch')) { 1672 instantHoverSwitch = options.instantHoverSwitch; 1673 } 1674 } 1675 1676 var timer = null; 1677 1678 $targets.bind('mouseenter', function () { 1679 var $this = $(this); 1680 1681 clearTimeout(timer); 1682 1683 if ($targets.filter('.hovered').length && instantHoverSwitch) { 1684 var $hovered = $targets.filter('.hovered'); 1685 $hovered.removeClass('hovered'); 1686 $hovered.each(function () { 1687 var $this = $(this); 1688 if ($this[0]._leaveCallback) $this[0]._leaveCallback(); 1689 }); 1690 $this.addClass('hovered'); 1691 } else { 1692 timer = setTimeout(function () { 1693 var $hovered = $targets.filter('.hovered'); 1694 $hovered.removeClass('hovered'); 1695 $hovered.each(function () { 1696 var $this = $(this); 1697 if ($this[0]._leaveCallback) $this[0]._leaveCallback(); 1698 }); 1699 $this.addClass('hovered'); 1700 if (options['enterCallback']) (options['enterCallback'].bind($this))(); 1701 }, enterDelay); 1702 } 1703 }); 1704 $targets.bind('mouseleave', function () { 1705 clearTimeout(timer); 1706 var $this = $(this); 1707 1708 if (options['leaveCallback']) { 1709 $this[0]._leaveCallback = function () { 1710 (options['leaveCallback'].bind($this))() 1711 }; 1712 } 1713 1714 if (!keepHover) { 1715 timer = setTimeout(function () { 1716 var $hovered = $targets.filter('.hovered'); 1717 $hovered.removeClass('hovered'); 1718 if ($this[0]._leaveCallback) $this[0]._leaveCallback(); 1719 }, leaveDelay); 1720 } else { 1721 if ($this[0]._leaveCallback) $this[0]._leaveCallback(); 1722 } 1723 }); 1724 1725 return true; 1726 } 1727}; 1728 1729/* 1730 [settings] { 1731 element: $, 1732 resolution: 1139, 1733 from: { 1734 element: $, 1735 method: one of ['appendTo', 'prependTo', 'insertAfter', 'insertBefore'], 1736 }, 1737 to: { 1738 element: $, 1739 method: one of ['appendTo', 'prependTo', 'insertAfter', 'insertBefore'], 1740 }, 1741 } 1742 */ 1743var ElementsMovingHandler = { 1744 _elements: [], 1745 _started: false, 1746 _methods: ['appendTo', 'prependTo', 'insertAfter', 'insertBefore'], 1747 add: function (settings) { 1748 if (typeof settings !== 'object') return console.error('bindElementMove: settings must be an object'); 1749 if (typeof settings.from !== 'object') return console.error('bindElementMove: settings.from must be an object'); 1750 if (typeof settings.to !== 'object') return console.error('bindElementMove: settings.to must be an object'); 1751 if (!settings.element.length) { 1752 console.warn('bindElementMove: Element not found', settings.element); 1753 return; 1754 } 1755 if (settings.element.length > 1) return console.error('bindElementsOrder: More than one element found: ' + settings.element.selector); 1756 if (!settings.from.element.length) return console.error('bindElementsOrder: Cant find [from] element: ' + settings.from.element.selector); 1757 if (settings.from.element.length > 1) return console.error('bindElementsOrder: More than one [from] element found: ' + settings.from.element.selector); 1758 if (!settings.to.element.length) return console.error('bindElementsOrder: Cant find [to] element: ' + settings.to.element.selector); 1759 if (settings.to.element.length > 1) return console.error('bindElementsOrder: More than one [to] element found: ' + settings.to.element.selector); 1760 if (this._methods.indexOf(settings.from.method) === -1) return console.error('bindElementsOrder: Unknown "to" method "' + settings.from.method + '". Alowed: ' + this._methods.join(', ')); 1761 if (this._methods.indexOf(settings.to.method) === -1) return console.error('bindElementsOrder: Unknown "from" method "' + settings.to.method + '". Alowed: ' + this._methods.join(', ')); 1762 if (typeof settings.resolution !== 'number') return console.error('bindElementsOrder: "resolution" must be a number'); 1763 if (settings.resolutionMin !== undefined && typeof settings.resolutionMin !== 'number') return console.error('bindElementsOrder: "resolutionMin" must be a number'); 1764 1765 if (!this._started) { 1766 this._init(); 1767 } 1768 1769 this._elements.push(settings); 1770 }, 1771 _init: function () { 1772 this._started = true; 1773 var that = this; 1774 $(window).bind('resize load', function () { 1775 for (var i = 0; i < that._elements.length; i++) { 1776 that._moveElement(that._elements[i]); 1777 if (typeof that._elements[i].callback === 'function') { 1778 that._elements[i].callback(); 1779 } 1780 } 1781 }); 1782 }, 1783 _moveElement: function (o) { 1784 if (windowWidth > o.resolution || (o.resolutionMin !== undefined && windowWidth <= o.resolutionMin)) { 1785 if (o.element[0].hasAttribute('data-moved')) { 1786 o.element[0].removeAttribute('data-moved'); 1787 o.element[o.from.method](o.from.element); 1788 } 1789 } else { 1790 if (!o.element[0].hasAttribute('data-moved')) { 1791 o.element[0].setAttribute('data-moved', true); 1792 o.element[o.to.method](o.to.element); 1793 } 1794 } 1795 }, 1796}; 1797 1798function footerToggleHandler() { 1799 var $footerBoxes = $(".footer-col-2, .footer-col-3"); 1800 var $footerBoxesTitle = $footerBoxes.find('.footer-col-title'); 1801 var $footerBoxesContent = $footerBoxes.find('.footer-col-content'); 1802 $footerBoxesTitle.bind("click touch", function () { 1803 var $this = $(this); 1804 var $toggled = $this.closest(".footer-col").find(".footer-col-content"); 1805 if (windowWidth <= 480) { 1806 if ($this.hasClass("active")) { 1807 $this.removeClass("active");
1808 $toggled.slideUp(); 1809 } else { 1810 $footerBoxesContent.slideUp(); 1811 $footerBoxesTitle.removeClass("active"); 1812 $this.addClass("active"); 1813 $toggled.slideDown(); 1814 } 1815 } 1816 }); 1817} 1818 1819function displaySelectedCount (select) { 1820 var $select = select.parent(); 1821 var selectedCount = $select.find(".select2-selection__choice").length; 1822 var total = $select.find("option").length; 1823 var text = "Wybrano " + selectedCount + " z " + total; 1824 1825 if (selectedCount === 0) return; 1826 1827 var setText = function () { 1828 $select.find(".select2-selection__rendered").html( 1829 "<span class=\"select2-selection__count\">" + text + "</span>" 1830 ); 1831 }; 1832 setText(); 1833 window.setTimeout(setText, 25); 1834} 1835 1836function initMovingElements() { 1837 ElementsMovingHandler.add({ 1838 element: $('.basket-box.top-box-container'), 1839 resolution: 1140, 1840 from: { 1841 element: $('.headerlink-list'), 1842 method: 'prependTo', 1843 }, 1844 to: { 1845 element: $('.rwd-menu-wrapper'), 1846 method: 'appendTo', 1847 } 1848 }); 1849}
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.