1/** 2 * Main scripts file 3 * 4 * @package Hestia 5 */ 6 7/* global jQuery */ 8/* global Hammer */ 9/* global AOS */ 10/* global requestpost */ 11 12jQuery( document ).ready( 13 function ( $ ) { 14 15 $.material.init(); 16 17 var window_width = $( window ).width(); 18 19 stickFooterToBottom(); 20 21 // Activate the Tooltips 22 $( '[data-toggle="tooltip"], [rel="tooltip"]' ).tooltip(); 23 24 // Activate bootstrap-select 25 $( '.select' ).dropdown( 26 { 27 'dropdownClass': 'dropdown-menu', 28 'optionClass': '' 29 } 30 ); 31 32 // Active Carousel 33 if ( $( 'body.rtl' ).length === 0 ) { 34 $( '.carousel' ).carousel( 35 { 36 interval: 10000 37 } 38 ); 39 // RTL 40 } else { 41 $( '.carousel' ).carousel( 42 { 43 interval: 10000 44 } 45 ); 46 $( '.carousel-control.left' ).click( 47 function () { 48 $( '.carousel' ).carousel( 'next' ); 49 } 50 ); 51 $( '.carousel-control.right' ).click( 52 function () { 53 $( '.carousel' ).carousel( 'prev' ); 54 } 55 ); 56 } 57 58 if ( typeof Hammer !== 'undefined' ) { 59 var hammerLeft = 'swipeleft', 60 hammerRight = 'swiperight'; 61 // RTL 62 if ( $( 'body.rtl' ).length !== 0 ) { 63 hammerLeft = 'swiperight'; 64 hammerRight = 'swipeleft'; 65 } 66 67 // Add swipe support on carousel 68 if ( $( '#carousel-hestia-generic' ).length !== 0 ) { 69 var hestiaCarousel = document.getElementById( 'carousel-hestia-generic' ); 70 Hammer( hestiaCarousel ).on( 71 hammerLeft, function () { 72 $( '.carousel' ).carousel( 'next' ); 73 } 74 ); 75 Hammer( hestiaCarousel ).on( 76 hammerRight, function () { 77 $( '.carousel' ).carousel( 'prev' ); 78 } 79 ); 80 } 81 } 82 var transparent = true; 83 84 if ( $( '.navbar-color-on-scroll' ).length !== 0 ) { 85 86 var navbarHome = $( '.navbar-color-on-scroll' ), 87 headerWithTopbar = 0; 88 89 if ( navbarHome.hasClass( 'header-with-topbar' ) ) { 90 headerWithTopbar = 40; 91 } 92 93 $( window ).on( 94 'scroll', debounce( 95 function () { 96 if ( $( document ).scrollTop() > headerWithTopbar ) { 97 if ( transparent ) { 98 transparent = false; 99 navbarHome.removeClass( 'navbar-transparent' ); 100 navbarHome.addClass( 'navbar-not-transparent' ); 101 } 102 } else { 103 if ( !transparent ) { 104 transparent = true; 105 navbarHome.addClass( 'navbar-transparent' ); 106 navbarHome.removeClass( 'navbar-not-transparent' ); 107 } 108 } 109 }, 17 110 ) 111 ); 112 } 113 114 // Check if header has topbar and add extra class 115 var navbar = $( '.navbar' ), 116 navbarScrollPoint = 0; 117 118 function checkNavbarScrollPoint() { 119 if ( $( '.navbar-header' ).length !== 0 ) { 120 121 // Window width bigger or equal with 768px 122 if ( getWidth() >= 768 ) { 123 if ( typeof $( '.navbar-header' ).offset() !== 'undefined' ) { 124 navbarScrollPoint = $( '.navbar-header' ).offset().top + $( '.navbar-header' ).height(); // Distance from top to the bottom of the logo 125 } 126 127 // Check if topbar is active when navbar is left aligned 128 if ( $( '.hestia_left.header-with-topbar' ).length !== 0 || $( '.full-screen-menu.header-with-topbar' ).length !== 0 ) { 129 navbarScrollPoint = 40; 130 } 131 132 // Window width less than 768px 133 } else { 134 // Check if topbar is active 135 if ( $( '.header-with-topbar' ).length !== 0 ) { 136 navbarScrollPoint = 40; // Topbar height 137 // Topbar disabled 138 } else { 139 navbarScrollPoint = 0; 140 } 141 } 142 } 143 } 144 145 checkNavbarScrollPoint(); 146 147 // On screen resize recalculate navbarScrollPoint 148 $( window ).resize( 149 function () { 150 checkNavbarScrollPoint(); 151 } 152 ); 153 154 // On screen scroll add scroll-related class 155 $( window ).on( 156 'scroll', function () { 157 if ( $( document ).scrollTop() >= navbarScrollPoint ) { 158 navbar.addClass( 'navbar-scroll-point' ); 159 } else { 160 navbar.removeClass( 'navbar-scroll-point' ); 161 } 162 } 163 ); 164 165 if ( window_width >= 768 ) { 166 var big_image = $( '.header-filter[data-parallax="active"]' ); 167 if ( big_image.length !== 0 ) { 168 $( window ).on( 169 'scroll', debounce( 170 function () { 171 if ( isElementInViewport( big_image ) ) { 172 var oVal = ($( window ).scrollTop() / 3); 173 big_image.css( 174 { 175 'transform': 'translate3d(0,' + oVal + 'px,0)', 176 '-webkit-transform': 'translate3d(0,' + oVal + 'px,0)', 177 '-ms-transform': 'translate3d(0,' + oVal + 'px,0)', 178 '-o-transform': 'translate3d(0,' + oVal + 'px,0)' 179 } 180 ); 181 } 182 }, 4 183 ) 184 ); 185 } 186 } 187 188 function stickFooterToBottom() { 189 var documentHeight = $( 'html' ).outerHeight( true ); 190 var windowHeight = $( window ).height(); 191 if ( documentHeight < windowHeight + 20 ) { 192 $( '.main .blog-post' ).css( 'min-height', $( '.main .blog-post' ).outerHeight() + windowHeight - documentHeight + 10 ); 193 } else { 194 $( '.main .blog-post' ).css( 'min-height', 'inherit' ); 195 } 196 } 197 198 function debounce( func, wait, immediate ) { 199 var timeout; 200 return function () { 201 var context = this, 202 args = arguments; 203 clearTimeout( timeout ); 204 timeout = setTimeout( 205 function () { 206 timeout = null; 207 if ( !immediate ) { 208 func.apply( context, args ); 209 } 210 }, wait 211 ); 212 if ( immediate && !timeout ) { 213 func.apply( context, args ); 214 } 215 }; 216 } 217 218 function isElementInViewport( elem ) { 219 var $elem = $( elem ); 220 221 // Get the scroll position of the page. 222 var viewportTop = $( window ).scrollTop(); 223 var viewportBottom = viewportTop + $( window ).height(); 224 225 // Get the position of the element on the page. 226 var elemTop = Math.round( $elem.offset().top ); 227 var elemBottom = elemTop + $elem.height(); 228 229 return ((elemTop < viewportBottom) && (elemBottom > viewportTop)); 230 } 231
232 /* Smooth Scroll */ 233 var verifiedNavHeight; 234 verifiedNavHeight = verifyNavHeight(); 235 236 // Verify again on resize 237 $( window ).resize( 238 function () { 239 verifiedNavHeight = verifyNavHeight(); 240 } 241 ); 242 243 function verifyNavHeight() { 244 var navHeight; 245 if ( window_width < 768 ) { 246 navHeight = $( '.navbar' ).outerHeight(); 247 } else { 248 navHeight = ( $( '.navbar' ).outerHeight() - 15 ); 249 } 250 return navHeight; 251 } 252 253 $( '.navbar a[href*="#"], a.btn[href*="#"]' ).click( 254 function () { 255 var menuitem = $( this ).attr( 'class' ); 256 if ( menuitem === 'dropdown-toggle' ) { 257 return; 258 } 259 if ( location.pathname.replace( /^\//, '' ) === this.pathname.replace( /^\//, '' ) && location.hostname === this.hostname ) { 260 var target = $( this.hash ); 261 target = target.length ? target : $( '[name=' + this.hash.slice( 1 ) + ']' ); 262 if ( target.length ) { 263 $( 'html,body' ).animate( 264 { 265 scrollTop: ( target.offset().top - verifiedNavHeight ) 266 }, 1200 267 ); 268 269 // Hide drop-down and submenu 270 if ( $( '.navbar .navbar-collapse' ).hasClass( 'in' ) ) { 271 $( '.navbar .navbar-collapse.in' ).removeClass( 'in' ); 272 } 273 if ( $( '.navbar li.dropdown' ).hasClass( 'open' ) ) { 274 $( '.navbar li.dropdown.open' ).removeClass( 'open' ); 275 } 276 if ( $( 'body' ).hasClass( 'menu-open' ) ) { 277 $( 'body' ).removeClass( 'menu-open' ); 278 $( '.navbar-collapse' ).css( 'height', '0' ); 279 $( '.navbar-toggle' ).attr( 'aria-expanded', 'false' ); 280 281 } 282 283 return false; 284 } 285 } 286 } 287 ); 288 289 // Add control-label for each contact form field 290 function addControlLabel( field ) { 291 var placeholderField = field.attr( 'placeholder' ); 292 field.removeAttr( 'placeholder' ); 293 $( '<label class="control-label"> ' + placeholderField + ' </label>' ).insertBefore( field ); 294 } 295 296 var searchForm = $( '.search-form label' ); 297 if ( typeof (searchForm) !== 'undefined' ) { 298 299 var searchField = $( searchForm ).find( '.search-field' ); 300 if ( $( searchField ).attr( 'value' ) === '' ) { 301 $( searchForm ).addClass( 'label-floating is-empty' ); 302 } else { 303 $( searchForm ).addClass( 'label-floating' ); 304 } 305 306 addControlLabel( searchField ); 307 } 308 309 var wooSearchForm = $( '.woocommerce-product-search' ); 310 if ( typeof (wooSearchForm) !== 'undefined' ) { 311 312 var wooSearchField = $( wooSearchForm ).find( '.search-field' ); 313 if ( $( wooSearchField ).attr( 'value' ) === '' ) { 314 $( wooSearchForm ).addClass( 'label-floating is-empty' ); 315 } else { 316 $( wooSearchForm ).addClass( 'label-floating' ); 317 } 318 319 addControlLabel( wooSearchField ); 320 } 321 322 if ( typeof $( '.contact_submit_wrap' ) !== 'undefined' ) { 323 $( '.pirate-forms-submit-button' ).addClass( 'btn btn-primary' ); 324 } 325 326 if ( typeof $( '.form_captcha_wrap' ) !== 'undefined' ) { 327 if ( $( '.form_captcha_wrap' ).hasClass( 'col-sm-4' ) ) { 328 $( '.form_captcha_wrap' ).removeClass( 'col-sm-6' ); 329 } 330 if ( $( '.form_captcha_wrap' ).hasClass( 'col-lg-6' ) ) { 331 $( '.form_captcha_wrap' ).removeClass( 'col-lg-6' ); 332 } 333 $( '.form_captcha_wrap' ).addClass( 'col-md-12' ); 334 } 335 336 if ( typeof $( 'form' ) !== 'undefined' ) { 337 $( 'form' ).addClass( 'form-group' ); 338 } 339 340 if ( typeof $( 'input' ) !== 'undefined' ) { 341 if ( typeof $( 'input[type="text"]' ) !== 'undefined' ) { 342 $( 'input[type="text"]' ).addClass( 'form-control' ); 343 } 344 345 if ( typeof $( 'input[type="email"]' ) !== 'undefined' ) { 346 $( 'input[type="email"]' ).addClass( 'form-control' ); 347 } 348 349 if ( typeof $( 'input[type="url"]' ) !== 'undefined' ) { 350 $( 'input[type="url"]' ).addClass( 'form-control' ); 351 } 352 353 if ( typeof $( 'input[type="password"]' ) !== 'undefined' ) { 354 $( 'input[type="password"]' ).addClass( 'form-control' ); 355 } 356 357 if ( typeof $( 'input[type="tel"]' ) !== 'undefined' ) { 358 $( 'input[type="tel"]' ).addClass( 'form-control' ); 359 } 360 361 if ( typeof $( 'input[type="search"]' ) !== 'undefined' ) { 362 $( 'input[type="search"]' ).addClass( 'form-control' ); 363 } 364 365 if ( typeof $( 'input.select2-input' ) !== 'undefined' ) { 366 $( 'input.select2-input' ).removeClass( 'form-control' ); 367 } 368 } 369 370 if ( typeof $( 'textarea' ) !== 'undefined' ) { 371 $( 'textarea' ).addClass( 'form-control' ); 372 } 373 374 if ( typeof $( '.form-control' ) !== 'undefined' ) { 375 $( '.form-control' ).parent().addClass( 'form-group' ); 376 377 $( window ).on( 378 'scroll', function () { 379 $( '.form-control' ).parent().addClass( 'form-group' ); 380 } 381 ); 382 } 383 384 $( window ).on( 385 'scroll', function () { 386 if ( $( 'body' ).hasClass( 'home' ) ) { 387 if ( $( window ).width() >= 751 ) { 388 var hestia_scrollTop = $( window ).scrollTop(); // cursor position 389 var headerHeight = $( '.navbar' ).outerHeight(); // header height
390 var isInOneSection = 'no'; // used for checking if the cursor is in one section or not 391 // for all sections check if the cursor is inside a section 392 $( '#carousel-hestia-generic, section' ).each( 393 function () { 394 var thisID = '#' + $( this ).attr( 'id' ); // section id 395 var hestia_offset = $( this ).offset().top; // distance between top and our section 396 var thisHeight = $( this ).outerHeight(); // section height 397 var thisBegin = hestia_offset - headerHeight; // where the section begins 398 var thisEnd = hestia_offset + thisHeight - headerHeight; // where the section ends 399 // if position of the cursor is inside of the this section 400 if ( hestia_scrollTop + verifiedNavHeight >= thisBegin && hestia_scrollTop + verifiedNavHeight <= thisEnd ) { 401 isInOneSection = 'yes'; 402 $( 'nav .on-section' ).removeClass( 'on-section' ); 403 $( 'nav a[href$="' + thisID + '"]' ).parent( 'li' ).addClass( 'on-section' ); // find the menu button with the same ID section 404 return false; 405 } 406 if ( isInOneSection === 'no' ) { 407 $( 'nav .on-section' ).removeClass( 'on-section' ); 408 } 409 } 410 ); 411 } 412 } 413 } 414 ); 415 416 $( document ).on( 417 'DOMNodeInserted', '.added_to_cart', function () { 418 if ( !( $( this ).parent().hasClass( 'hestia-view-cart-wrapper' ) ) ) { 419 $( this ).wrap( '<div class="hestia-view-cart-wrapper"></div>' ); 420 } 421 } 422 ); 423 424 /** 425 * Add padding in post/page header 426 */ 427 function fixHeaderPadding() { 428 429 /** 430 * This code is related to hestia_header_layout control. 431 * Handle the classic blog header layout. 432 * 433 * Because of the scroll bar on Windows, $( window ).width() is not the same with the media query, so we 434 * need matchMedia to target the media queries. 435 * See more info here: https://www.sitepoint.com/javascript-media-queries/ 436 * 437 * - On mobile < 600px with admin bar (which becomes fixed) we have to adjust the margin of the content container 438 * so that the navigation bar doesn't overlap it. 439 * - In all other cases we should just adjust the margin with the navigation bar height. 440 */ 441 var navbar_height = $( '.navbar-fixed-top' ).outerHeight(); 442 var mobile_media = window.matchMedia( '(max-width: 600px)' ); 443 if( $('#wpadminbar').length && mobile_media.matches ) { 444 $('.main.classic-blog').css('margin-top', navbar_height - 46); 445 } else { 446 $('.main.classic-blog').css('margin-top', navbar_height); 447 } 448 449 if ( $( window ).width() > 768 ) { 450 var beaver_offset = 40; 451 $( '.pagebuilder-section' ).css( 'padding-top', navbar_height ); 452 $( '.fl-builder-edit .pagebuilder-section' ).css( 'padding-top', navbar_height + beaver_offset ); 453 $( '.page-header.header-small .container' ).css( 'padding-top', navbar_height + 100 ); 454 var headerHeight = $( '.single-product .page-header.header-small' ).height(); 455 var offset = headerHeight + 100; 456 $( '.single-product .page-header.header-small .container' ).css( 'padding-top', headerHeight - offset ); 457 458 var marginOffset = headerHeight - navbar_height - 172; 459 $( '.woocommerce.single-product .blog-post .col-md-12 > div[id^=product].product' ).css( 'margin-top', -marginOffset ); 460 } else { 461 $( '.page-header.header-small .container , .woocommerce.single-product .blog-post .col-md-12 > div[id^=product].product' ).removeAttr( 'style' ); 462 } 463 if( $('.no-content').length ) { 464 $('.page-header.header-small').css('min-height', navbar_height + 230); 465 } 466 } 467 468 fixHeaderPadding(); 469 470 /** 471 * Calculate height for .page-header on front page 472 */ 473 function headerSpacingFrontpage() { 474 if ( $( '.home .header .carousel' ).length > 0 ) { 475 var pageHeader = $( '.page-header' ), 476 pageHeaderContainer = $( '.page-header .container' ), 477 windowWidth = $( window ).width(), 478 windowHeight = $( window ).height(); 479 480 // Set page-header height 481 if ( windowWidth > 768 ) { 482 pageHeader.css( 'height', (windowHeight * 0.9) ); // 90% of window height 483 } else { 484 if ( windowHeight > pageHeaderContainer.outerHeight() ) { 485 pageHeader.css( 'height', windowHeight ); // window height is 100% 486 pageHeaderContainer.removeClass( 'container-height-auto' ); 487 } else { 488 pageHeader.css( 'height', 'auto' ); // window height will be auto 489 pageHeaderContainer.addClass( 'container-height-auto' ); 490 } 491 } 492 } 493 } 494 495 headerSpacingFrontpage(); 496 497 // Fix for Bootstrap Navwalker 498 $( '.navbar .dropdown > a .caret' ).click( 499 function (event) { 500 event.preventDefault(); 501 event.stopPropagation(); 502 $( this ).toggleClass( 'caret-open' ); 503 $( this ).parent().siblings().toggleClass( 'open' ); 504 505 if ( $( '.navbar .dropdown' ).hasClass( 'open' ) ) { 506 $( '.navbar .dropdown' ).removeClass( 'open' ); 507 $( this ).toggleClass( 'caret-open' ); 508 $( this ).parent().siblings().toggleClass( 'open' ); 509 } 510 } 511 ); 512 513 // Add active parent links on navigation 514 $( '.navbar .dropdown > a' ).click( 515 function () { 516 location.href = this.href; 517 } 518 ); 519 520 /** 521 * Detect if browser is iPhone or iPad then add body class 522 */ 523 function hestia_detect_ios() { 524 if ( $( '.hestia-about' ).length > 0 || $( '.hestia-ribbon' ).length > 0 ) { 525 var iOS = /iPad|iPhone|iPod/.test( navigator.userAgent ) && !window.MSStream; 526 527 if ( iOS ) { 528 $( 'body' ).addClass( 'is-ios' ); 529 } 530 } 531 } 532 533 hestia_detect_ios(); 534 535 // Add size for each search input in top-bar 536 if ( $( '.hestia-top-bar input[type=search]' ).length > 0 ) { 537 $( '.hestia-top-bar input[type=search]' ).each( 538 function () { 539 $( this ).attr( 'size', $( this ).parent().find( '.control-label' ).text().replace( / |â¦/g, '' ).length ); 540 } 541 ); 542 } 543 544 // Functions on window resize 545 $( window ).resize( 546 function () { 547 setTimeout( stickFooterToBottom(), 500 ); 548 fixHeaderPadding(); 549 headerSpacingFrontpage(); 550 } 551 ); 552 553 // Very important! Don't Delete. 554 var navigation = $( '#main-navigation' ); 555 navigation.on( 556 'show.bs.collapse', function () { 557 $( 'body' ).addClass( 'menu-open' ); 558 } 559 ); 560 navigation.on( 561 'hidden.bs.collapse', function () { 562 $( 'body' ).removeClass( 'menu-open' ); 563 } 564 ); 565 566 // Get window width 567 function getWidth() { 568 if ( this.innerWidth ) { 569 return this.innerWidth; 570 } 571 572 if ( document.documentElement && document.documentElement.clientWidth ) { 573 return document.documentElement.clientWidth; 574 } 575 576 if ( document.body ) { 577 return document.body.clientWidth; 578 } 579 } 580 581 $.hestia = { 582 'init': function () { 583 this.navSearch(); 584 this.getPortfolioModalData(); 585 this.initAnimations(); 586 }, 587 588 'navSearch': function () { 589 $( '.hestia-toggle-search' ).on( 'click', function () { 590 $( '.navbar' ).toggleClass( 'nav-searching' ); 591 $( '.nav-searching' ).find( '.hestia-nav-search' ).addClass( 'is-focused' ); 592 $( '.nav-searching' ).find( '.hestia-nav-search' ).find( '.search-field' ).focus(); 593 $( this ).find( 'i' ) 594 .fadeOut( 200, function () { 595 $( this ).toggleClass( 'fa-search' ); 596 $( this ).toggleClass( 'fa-times' ); 597 } ).fadeIn( 200 ); 598 } ); 599 }, 600 601 /** 602 * This function is used for grabbing post content via Ajax. 603 * It triggers when the modal is open. 604 */ 605 'getPortfolioModalData': function () { 606 $('div[data-toggle="modal"]').on('click', function () { 607 var pid = $(this).data('pid'); 608 609 $.ajax( 610 { 611 url: requestpost.ajaxurl, 612 type: 'post', 613 data: { 614 action: 'hestia_get_portfolio_item_data', 615 pid: pid 616 }, 617 success: function (result) { 618 var modal = $('.hestia-portfolio-modal');
619 modal.find('.modal-content').html(result); 620 modal.on('hidden.bs.modal', function () { 621 var html = '<div class="portfolio-loading text-center"><i class="fa fa-3x fa-spin fa-circle-o-notch"></i></div>'; 622 $(this).find('.modal-content').html(html); 623 }); 624 } 625 } 626 ); 627 }); 628 629 }, 630 631 'initAnimations': function(){ 632 if ( typeof AOS !== 'undefined' ) { 633 var aosOpt = { 634 offset: 250, 635 delay: 300, 636 duration: 900, 637 once: true, 638 disable: 'mobile' 639 }; 640 AOS.init(aosOpt); 641 } 642 } 643 }; 644 $.hestia.init(); 645 646 } 647); 648 649(function ( $ ) { 650 $( window ).load( 651 function () { 652 // Sidebar toggle 653 if ( $( '.blog-sidebar-wrapper,.shop-sidebar-wrapper' ).length > 0 ) { 654 var sidebarOrientation = 'left'; 655 656 // RTL 657 if ( $( 'body.rtl' ).length !== 0 ) { 658 sidebarOrientation = 'right'; 659 } 660 661 $( '.hestia-sidebar-open' ).click( 662 function () { 663 $( '.sidebar-toggle-container' ).css( sidebarOrientation, '0' ); 664 } 665 ); 666 667 $( '.hestia-sidebar-close' ).click( 668 function () { 669 $( '.sidebar-toggle-container' ).css( sidebarOrientation, '-100%' ); 670 } 671 ); 672 } 673 } 674 ); 675 676 var showScrollToTop = 0; 677 $( window ).on( 'scroll', function () { 678 679 var y_scroll_pos = window.pageYOffset; 680 var scroll_pos_test = $( 'header' ).height(); 681 682 if ( y_scroll_pos > scroll_pos_test && showScrollToTop === 0 ) { 683 $( '.hestia-scroll-to-top' ).addClass( 'hestia-fade' ); 684 showScrollToTop = 1; 685 } 686 687 if ( y_scroll_pos < scroll_pos_test && showScrollToTop === 1 ) { 688 $( '.hestia-scroll-to-top' ).removeClass( 'hestia-fade' ); 689 showScrollToTop = 0; 690 } 691 692 } ); 693 694 $( '.hestia-scroll-to-top' ).on( 'click', function () { 695 window.scroll( { 696 top: 0, 697 behavior: 'smooth' 698 } ); 699 } ); 700 701}( jQuery ));
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.