1( function( $ ) { 2 'use strict'; 3 4 var JetMenuPlugin = function( element, options ) { 5 6 this.defaultSettings = { 7 enabled: false, 8 mouseLeaveDelay: 500, 9 openSubType: 'click', // hover, click 10 ajaxLoad: true, 11 megaWidthType: 'container', 12 megaWidthSelector: '', 13 mainMenuSelector: '.jet-menu', 14 menuItemSelector: '.jet-menu-item', 15 moreMenuContent: '···' 16 } 17 18 this.settings = $.extend( this.defaultSettings, options ); 19 20 this.$window = $( window ); 21 22 this.$document = $( document ); 23 24 this.$element = $( element ); 25 26 this.$instance = $( this.settings.mainMenuSelector, this.$element ).addClass( 'jet-responsive-menu' ); 27 28 this.$menuItems = $( '>' + this.settings.menuItemSelector, this.$instance ).addClass( 'jet-responsive-menu-item' ); 29 30 this.$moreItemsInstance = null; 31 32 this.hiddenItemsArray = []; 33 34 this.createMenuInstance(); 35 36 this.$instance.trigger( 'jetMenuCreated' ); 37 38 return this; 39 } 40 41 JetMenuPlugin.prototype = { 42 constructor: JetMenuPlugin, 43 44 self: this, 45 46 createMenuInstance: function() { 47 var self = this, 48 mainMenuWidth, 49 totalVisibleItemsWidth = 0; 50 51 this.subMenuRebuild(); 52 this.subMegaMenuRebuild(); 53 54 // Add available items list 55 if ( ! tools.isEmpty( this.settings.moreMenuContent ) && self.settings.enabled ) { 56 self.$instance.append( '<li class="jet-menu-item jet-menu-item-has-children jet-simple-menu-item jet-responsive-menu-available-items" hidden><a href="#" class="top-level-link"><div class="jet-menu-item-wrapper">' + this.settings.moreMenuContent + '</div></a><ul class="jet-sub-menu"></ul></li>' ); 57 self.$moreItemsInstance = $( '> .jet-responsive-menu-available-items', this.$instance ); 58 self.$moreItemsInstance.attr( { 'hidden': 'hidden' } ); 59 } 60 61 this.rebuildItems(); 62 this.$instance.trigger( 'rebuildItems' ); // subMenu position rebuild 63 64 this.subMenuHandler(); 65 66 this.watch(); 67 }, 68 69 /** 70 * SubMenu items Handler. 71 * 72 * @return {void} 73 */ 74 subMenuHandler: function() { 75 var self = this, 76 transitionend = 'transitionend oTransitionEnd webkitTransitionEnd', 77 prevClickedItem = null, 78 menuItem, 79 menuItemParents, 80 timer; 81 82 switch ( this.settings.openSubType ) { 83 case 'hover': 84 this.$instance.on( 'mouseenter', '.jet-menu-item > a', { instance: this }, mouseEnterHandler ); 85 this.$instance.on( 'mouseleave', '.jet-menu-item > a', mouseLeaveHandler ); 86 break; 87 88 case 'click': 89 this.$instance.on( 'click', '.jet-menu-item > a', { instance: this }, clickHandler ); 90 break; 91 } 92 93 this.$instance.on( 'mouseenter', '.jet-sub-menu, .jet-sub-mega-menu', mouseEnterSubMenuHandler ); 94 this.$instance.on( 'mouseenter', mouseEnterInstanceHandler ); 95 this.$instance.on( 'mouseleave', mouseLeaveInstanceHandler ); 96 97 function clickHandler( event ) { 98 var $this, 99 $siblingsItems, 100 $link, 101 $currentTarget, 102 subMenu, 103 templateId, 104 instance = event.data.instance; 105 106 event.preventDefault(); 107 event.stopPropagation(); 108 109 $currentTarget = $( event.currentTarget ); 110 $this = $currentTarget.closest('.jet-menu-item'); 111 $siblingsItems = $this.siblings( '.jet-menu-item.jet-menu-item-has-children' ); 112 $link = $( '> a', $this ); 113 subMenu = $( '.jet-sub-menu:first, .jet-sub-mega-menu', $this ); 114 templateId = subMenu.data( 'template-id' ) || false; 115 116 if ( $siblingsItems[0] ) { 117 $siblingsItems.removeClass( 'jet-menu-hover' ); 118 $( 'jet-menu-item-has-children', $siblingsItems ).removeClass( 'jet-menu-hover' ); 119 } 120 121 if ( ! $( '.jet-sub-menu, .jet-sub-mega-menu', $this )[0] || $this.hasClass('jet-menu-hover') ) { 122 window.location = $link.attr( 'href' ); 123 124 return false; 125 } 126 127 if ( subMenu[0] ) { 128 $this.addClass( 'jet-menu-hover' ); 129 130 if ( templateId ) { 131 instance.maybeTemplateLoad( templateId, subMenu ); 132 } 133 } 134 } 135 136 function mouseEnterHandler( event ) { 137 var subMenu, 138 templateId, 139 instance; 140 141 menuItem = $( event.target ).parents( '.jet-menu-item' ); 142 subMenu = menuItem.children( '.jet-sub-menu, .jet-sub-mega-menu' ).first(); 143 templateId = subMenu.data( 'template-id' ) || false; 144 instance = event.data.instance; 145 146 $( '.jet-menu-hover', this.$instance ).removeClass( 'jet-menu-hover' ); 147 148 if ( subMenu[0] ) { 149 menuItem.addClass( 'jet-menu-hover' ); 150 151 if ( templateId ) { 152 instance.maybeTemplateLoad( templateId, subMenu ); 153 } 154 } 155 } 156 157 function mouseLeaveHandler( event ) { 158 // Item Mouse Leave Event 159 } 160 161 function mouseEnterSubMenuHandler( event ) { 162 clearTimeout( timer ); 163 } 164 165 function mouseEnterInstanceHandler( event ) { 166 clearTimeout( timer ); 167 } 168 169 function mouseLeaveInstanceHandler( event ) { 170 timer = setTimeout( function() { 171 $( '.jet-menu-hover', this.$instance ).removeClass( 'jet-menu-hover' ); 172 }, self.settings.mouseLeaveDelay ); 173 } 174 175 var windowWidth = $( window ).width(); 176 177 self.$window.on( 'orientationchange resize', function( event ) { 178
179 // Do not trigger a change if the viewport hasn't actually changed. Scrolling on iOS will trigger a resize. 180 if ( $( window ).width() === windowWidth ) { 181 return; 182 } 183 184 windowWidth = $( window ).width(); 185 186 self.$instance.find( '.jet-menu-item' ).removeClass( 'jet-menu-hover' ); 187 } ); 188 189 self.$document.on( 'touchend', function( event ) { 190 191 if ( $( event.target ).closest( '.jet-menu-item' ).length ) { 192 return; 193 } 194 195 self.$instance.find( '.jet-menu-item' ).removeClass( 'jet-menu-hover' ); 196 } ); 197 198 }, 199 200 maybeTemplateLoad: function( templateId, $templateContainer ) { 201 202 if ( ! this.settings.ajaxLoad ) { 203 return; 204 } 205 206 if ( $templateContainer.hasClass( 'template-loaded' ) ) { 207 return; 208 } 209 210 $.ajax( { 211 type: 'GET', 212 url: window.jetMenuPublicSettings.templateApiUrl, 213 dataType: 'json', 214 data: { 215 'id': templateId, 216 'dev': window.jetMenuPublicSettings.devMode 217 }, 218 beforeSend: function( jqXHR, ajaxSettings ) { 219 220 }, 221 success: function( responce, textStatus, jqXHR ) { 222 var templateContent = responce['template_content'], 223 templateScripts = responce['template_scripts'], 224 templateStyles = responce['template_styles']; 225 226 for ( var scriptHandler in templateScripts ) { 227 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 228 } 229 230 for ( var styleHandler in templateStyles ) { 231 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 232 } 233 234 $templateContainer.addClass( 'template-loaded' ); 235 236 jetMenu.elementorContentRender( $templateContainer, templateContent ); 237 } 238 } ); 239 }, 240 241 /** 242 * Responsive menu watcher function. 243 * 244 * @param {number} Watcher debounce delay. 245 * @return {void} 246 */ 247 watch: function( delay ) { 248 var delay = delay || 10; 249 250 $( window ).on( 'resize.jetResponsiveMenu orientationchange.jetResponsiveMenu load.jetResponsiveMenu', this.debounce( delay, this.watcher.bind( this ) ) ); 251 this.$instance.trigger( 'containerResize' ); 252 }, 253 254 /** 255 * Responsive menu watcher callback. 256 * 257 * @param {Object} Resize or Orientationchange event. 258 * @return {void} 259 */ 260 watcher: function( event ) { 261 this.rebuildItems(); 262 this.$instance.trigger( 'rebuildItems' ); // subMenu position rebuild 263 this.$instance.trigger( 'containerResize' ); 264 }, 265 266 /** 267 * Responsive Menu rebuilding function. 268 * 269 * @return {void} 270 */ 271 rebuildItems: function() { 272 273 if ( ! this.settings.enabled ) { 274 return false; 275 } 276 277 var self = this, 278 mainMenuWidth = this.$instance.width(), 279 correctedMenuWidth = this.$instance.width() - self.$moreItemsInstance.outerWidth( true ), 280 iterationVisibleItemsWidth = 0, 281 iterationHiddenItemsWidth = this.getVisibleItemsWidth(), 282 visibleItemsArray = [], 283 hiddenItemsArray = []; 284 285 self.$menuItems.each( function() { 286 var $this = $( this ); 287 288 iterationVisibleItemsWidth += $this.outerWidth( true ); 289 290 if ( iterationVisibleItemsWidth > correctedMenuWidth && ! tools.inArray( this, hiddenItemsArray ) ) { 291 hiddenItemsArray.push( this ); 292 } else { 293 visibleItemsArray.push( this ); 294 } 295 296 } ); 297 298 hiddenItemsArray.forEach( function( item ) { 299 var $item = $( item ); 300 301 $item.attr( { 'hidden': 'hidden' } ); 302 } ); 303 304 visibleItemsArray.forEach( function( item, index ) { 305 var $item = $( item ); 306 307 $item.removeAttr( 'hidden' ); 308 } ); 309 310 $( '> .jet-sub-menu', self.$moreItemsInstance ).empty(); 311 312 hiddenItemsArray.forEach( function( item ) { 313 var $clone = $( item ).clone(); 314 315 // Remove sub-mega-menu content 316 $( '.jet-sub-mega-menu', $clone ).remove(); 317 318 $clone.addClass( 'jet-sub-menu-item' ); 319 320 $clone.removeAttr( 'hidden' ); 321 322 $( '> .top-level-link', $clone ).toggleClass( 'top-level-link sub-level-link' ); 323 324 $( '> .jet-sub-menu', self.$moreItemsInstance ).append( $clone ); 325 } ); 326 327 if ( 0 == hiddenItemsArray.length ) { 328 self.$moreItemsInstance.attr( { 'hidden': 'hidden' } ); 329 self.$moreItemsInstance.addClass( 'jet-empty' ); 330 } else { 331 self.$moreItemsInstance.removeAttr( 'hidden' ); 332 self.$moreItemsInstance.removeClass( 'jet-empty' ); 333 } 334 335 self.hiddenItemsArray = hiddenItemsArray; 336 }, 337 338 /** 339 * Sub Menu rebuilding function. 340 * 341 * @return {void} 342 */ 343 subMenuRebuild: function() { 344 var self = this, 345 initSubMenuPosition = false;
346 347 this.$instance.on( 'rebuildItems', function() { 348 var $subMenuList = $( '.jet-sub-menu', self.$instance ), 349 maxWidth = self.$window.outerWidth( true ), 350 isRTL = $( 'body' ).hasClass( 'rtl' ); 351 352 if ( ! $subMenuList[0] ) { 353 return; 354 } 355 356 if ( initSubMenuPosition ) { 357 $subMenuList.removeClass( 'inverse-side' ); 358 initSubMenuPosition = false; 359 } 360 361 $subMenuList.each( function() { 362 var $this = $( this ), 363 subMenuOffset = $this.offset().left, 364 subMenuPos = subMenuOffset + $this.outerWidth( true ); 365 366 if ( ! isRTL ) { 367 if ( subMenuPos >= maxWidth ) { 368 $this.addClass( 'inverse-side' ); 369 $this.find( '.jet-sub-menu' ).addClass( 'inverse-side' ); 370 371 initSubMenuPosition = true; 372 } else if ( subMenuOffset < 0 ) { 373 $this.removeClass( 'inverse-side' ); 374 $this.find( '.jet-sub-menu' ).removeClass( 'inverse-side' ); 375 } 376 } else { 377 if ( subMenuOffset < 0 ) { 378 $this.addClass( 'inverse-side' ); 379 $this.find( '.jet-sub-menu' ).addClass( 'inverse-side' ); 380 381 initSubMenuPosition = true; 382 } else if ( subMenuPos >= maxWidth ) { 383 $this.removeClass( 'inverse-side' ); 384 $this.find( '.jet-sub-menu' ).removeClass( 'inverse-side' ); 385 } 386 } 387 388 } ); 389 } ); 390 }, 391 392 /** 393 * Sub Mega Menu rebuilding function. 394 * 395 * @return {void} 396 */ 397 subMegaMenuRebuild: function() { 398 var self = this; 399 400 this.$instance.on( 'containerResize', function() { 401 var $megaMenuList = $( '.jet-sub-mega-menu', self.$instance ), 402 maxWidth = $( 'body' ).outerWidth( true ); 403 404 switch( self.settings.megaWidthType ) { 405 case 'items': 406 var visibleItemsWidth = self.getVisibleItemsWidth(), 407 firstOffset = $( '> .jet-menu-item:first', self.$instance ).position().left; 408 409 $megaMenuList.css( { 410 'width': visibleItemsWidth + 'px', 411 'left': firstOffset 412 } ); 413 break; 414 case 'selector': 415 var customSelector = $( self.settings.megaWidthSelector ), 416 instanceOffset = null, 417 customSelectorOffset = null; 418 419 if ( customSelector[0] ) { 420 instanceOffset = self.$instance.offset().left; 421 customSelectorOffset = customSelector.offset().left; 422 423 $megaMenuList.css( { 424 'width': customSelector.outerWidth(), 425 'left': (customSelectorOffset - instanceOffset ) + 'px' 426 } ); 427 } 428 429 break; 430 } 431 432 if ( $megaMenuList[0] ) { 433 $megaMenuList.css( { 434 'maxWidth': '' 435 } ); 436 437 $megaMenuList.each( function() { 438 var $this = $( this ), 439 megaMenuOffsetLeft = $this.offset().left, 440 megaMenuOffsetRight = megaMenuOffsetLeft + $this.outerWidth( true ); 441 442 if ( megaMenuOffsetRight >= maxWidth ) { 443 $this.css( { 444 'maxWidth': maxWidth - megaMenuOffsetLeft 445 } ); 446 } 447 } ); 448 } 449 } ); 450 }, 451 452 /** 453 * Get visible items total width 454 * 455 * @return {int} 456 */ 457 getVisibleItemsWidth: function() { 458 var totalVisibleItemsWidth = 0; 459 460 this.$menuItems.each( function() { 461 var $this = $( this ); 462 463 if ( ! $this.hasAttr( 'hidden' ) ) { 464 totalVisibleItemsWidth += $this.outerWidth( true ); 465 } 466 } ); 467 468 return totalVisibleItemsWidth; 469 }, 470 471 /** 472 * Mobile and tablet check funcion. 473 * 474 * @return {boolean} Mobile Status 475 */ 476 mobileAndTabletcheck: function() { 477 var check = false; 478 479 (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|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|xda|xiino|android|ipad|playbook|silk/i.test(a)||/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 )|
479sy(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(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); 480 481 return check; 482 }, 483 484 /** 485 * Debounce the function call 486 * 487 * @param {number} threshold The delay. 488 * @param {Function} callback The function. 489 */ 490 debounce: function ( threshold, callback ) { 491 var timeout; 492 493 return function debounced( $event ) { 494 function delayed() { 495 callback.call( this, $event ); 496 timeout = null; 497 } 498 499 if ( timeout ) { 500 clearTimeout( timeout ); 501 } 502 503 timeout = setTimeout( delayed, threshold ); 504 }; 505 } 506 } 507 508 /* 509 * Js tools 510 */ 511 var tools = { 512 isEmpty: function( value ) { 513 return ( ( false === value ) || ( '' === value ) || ( null === value ) || ( undefined === value )); 514 }, 515 516 isEmptyObject: function( value ) { 517 return ( true === this.isEmpty( value ) ) || ( 0 === value.length ); 518 }, 519 520 isString: function(value) { 521 return ( ( 'string' === typeof value ) || ( value instanceof String ) ); 522 }, 523 524 isArray: function( value ) { 525 return $.isArray( value ); 526 }, 527 528 inArray: function( value, array ) { 529 return ( $.inArray( value, array ) !== -1); 530 } 531 }; 532 533 /* 534 * Jq tools 535 */ 536 $.fn.hasAttr = function( name ) { 537 return this.attr( name ) !== undefined; 538 }; 539 540 // jQuery plugin 541 $.fn.JetMenuPlugin = function( options ) { 542 return this.each( function() { 543 var $this = $( this ), 544 pluginOptions = ( 'object' === typeof options ) ? options : {}; 545 546 if ( ! $this.data( 'JetMenuPlugin' ) ) { 547 548 // create plugin instance (only if not exists) and expose the entire instance API 549 $this.data( 'JetMenuPlugin', new JetMenuPlugin( this, pluginOptions ) ); 550 } 551 } ); 552 }; 553 554}( jQuery ) ); 555 556( function( $ ) { 557 'use strict'; 558 559 window.jetMenu = { 560 561 addedScripts: {}, 562 563 addedStyles: {}, 564 565 addedAssetsPromises: [], 566 567 initedMobileMenuInstance: [], 568 569 eventBus: new Vue(), 570 571 $body: $( 'body' ), 572 573 init: function() { 574 this.initDesktopMenu(); 575 this.mobileVueComponents(); 576 this.initMobileMenu(); 577 }, 578 579 initDesktopMenu: function() { 580 var rollUp = false, 581 jetMenuMouseleaveDelay = 500, 582 jetMenuMegaWidthType = 'container', 583 jetMenuMegaWidthSelector = '', 584 jetMenuMegaOpenSubType = 'hover', 585 jetMenuMegaAjax = false; 586 587 if ( window.jetMenuPublicSettings && window.jetMenuPublicSettings.menuSettings ) { 588 rollUp = ( 'true' === jetMenuPublicSettings.menuSettings.jetMenuRollUp ) ? true : false; 589 jetMenuMouseleaveDelay = jetMenuPublicSettings.menuSettings.jetMenuMouseleaveDelay || 500; 590 jetMenuMegaWidthType = jetMenuPublicSettings.menuSettings.jetMenuMegaWidthType || 'container'; 591 jetMenuMegaWidthSelector = jetMenuPublicSettings.menuSettings.jetMenuMegaWidthSelector || ''; 592 jetMenuMegaOpenSubType = jetMenuPublicSettings.menuSettings.jetMenuMegaOpenSubType || 'hover'; 593 jetMenuMegaAjax = ( 'true' === jetMenuPublicSettings.menuSettings.jetMenuMegaAjax ) ? true : false; 594 } 595 596 $( '.jet-menu-container' ).JetMenuPlugin( { 597 enabled: rollUp, 598 mouseLeaveDelay: +jetMenuMouseleaveDelay, 599 megaWidthType: jetMenuMegaWidthType, 600 megaWidthSelector: jetMenuMegaWidthSelector, 601 openSubType: jetMenuMegaOpenSubType, 602 ajaxLoad: jetMenuMegaAjax, 603 } ); 604 605 }, 606 607 initMobileMenu: function() { 608 609 let mobileMenuList = $( '.jet-mobile-menu-single' ); 610 611 if ( ! mobileMenuList[0] ) { 612 return false; 613 } 614 615 if ( 'true' === window.jetMenuPublicSettings.devMode ) { 616 Vue.config.devtools = true; 617 } 618 619 mobileMenuList.each( function() { 620 let $this = $( this ), 621 menuInstanceId = $this.attr( 'id' ), 622 menuId = $this.data( 'menu-id' ) || false, 623 menuOptions = $this.data( 'menu-options' ) || {}; 624 625 jetMenu.createMobileMenuInstance( menuInstanceId, menuId, menuOptions ); 626 } ); 627 }, 628 629 createMobileMenuInstance: function( menuInstanceId, menuId, menuOptions ) { 630 631 if ( jetMenu.initedMobileMenuInstance.includes( menuInstanceId ) ) { 632 return; 633 } 634 635 jetMenu.initedMobileMenuInstance.push( menuInstanceId ); 636 637 let mobileMenuInstance = new Vue( { 638 el: '#' + menuInstanceId, 639 data: { 640 'uniqId': menuInstanceId, 641 'menuOptions': menuOptions, 642 } 643 } ); 644 }, 645 646 mobileVueComponents: function() { 647 648 Vue.component( 'mobilemenuitem', { 649 template: '#mobile-menu-item-template', 650 651 props: { 652 itemDataObject: Object, 653 depth: Number, 654 menuOptions: Object 655 }, 656 657 data: function() { 658 return ( { 659 ajaxRequest: null, 660 templateLoadStatus: false, 661 } ) 662 }, 663 664 computed: { 665 666 itemClasses: function() { 667 let itemClasses = [ 668 `jet-mobile-menu__item`, 669 `jet-menu-item-${ this.itemDataObject.itemId }`, 670 `jet-mobile-menu__item--sub-trigger-${ this.menuOptions.subTrigger || 'item' }` 671 ]; 672 673 if ( window.location.href === this.itemDataObject.url ) { 674 itemClasses.push( 'jet-mobile-menu__item--active'); 675 } 676 677 return itemClasses; 678 }, 679 680 isСhildrenDefine: function() { 681 return this.itemDataObject.children ? true : false;
682 }, 683 684 isTemplateDefine: function() { 685 return false !== this.itemDataObject.elementorTemplateId ? true : false; 686 }, 687 688 isSub: function() { 689 return this.isСhildrenDefine || this.isTemplateDefine ? true : false; 690 }, 691 692 isTopLevel: function() { 693 return 0 === this.depth ? true : false; 694 }, 695 696 depthClass: function() { 697 return 0 === this.depth ? 'mobile-top-level-link' : 'mobile-sub-level-link'; 698 }, 699 700 dropdownIconHtml: function() { 701 return '' !== this.menuOptions.dropdownIcon ? this.menuOptions.dropdownIcon : '<i class="fas fa-angle-right"></i>'; 702 }, 703 704 itemIconHtml: function() { 705 return this.itemDataObject.itemIcon; 706 }, 707 708 isIconVisible: function() { 709 let iconVisible = this.menuOptions['itemIconVisible'] || 'true'; 710 711 return 'false' === iconVisible || '' === this.itemDataObject.itemIcon || ! this.itemDataObject.itemIcon ? false : true; 712 }, 713 714 isBadgeVisible: function() { 715 let badgeVisible = this.menuOptions['itemBadgeVisible'] || 'true'; 716 717 return 'false' === badgeVisible || '' === this.itemDataObject.badgeText || ! this.itemDataObject.badgeText ? false : true; 718 }, 719 720 isDescVisible: function() { 721 let descVisible = this.menuOptions['itemDescVisible'] || 'false'; 722 723 return 'false' === descVisible || '' === this.itemDataObject.description || ! this.itemDataObject.description ? false : true; 724 }, 725 726 loaderColor: function() { 727 return this.menuOptions.loaderColor || '#3a3a3a'; 728 }, 729 }, 730 731 methods: { 732 itemSubHandler: function( event ) { 733 734 if ( 'item' !== this.menuOptions.subTrigger ) { 735 return; 736 } 737 738 let target = event.target, 739 mobileLink = target.closest( '.mobile-link' ); 740 741 if ( this.isSub && mobileLink ) { 742 event.preventDefault(); 743 } 744 745 this.switchToSub( event ); 746 }, 747 748 maskerSubHandler: function( event ) { 749 750 if ( 'submarker' !== this.menuOptions.subTrigger ) { 751 return; 752 } 753 754 this.switchToSub( event ); 755 }, 756 757 switchToSub: function( event ) { 758 759 if ( ! this.isSub ) { 760 return; 761 } 762 763 if ( ! this.isTemplateDefine ) { 764 765 jetMenu.eventBus.$emit( 'itemsSubSwitch', { 766 menuUniqId: this.menuOptions.menuUniqId, 767 id: this.itemDataObject.id, 768 name: this.itemDataObject.name, 769 children: this.itemDataObject.children || false 770 } ); 771 772 } else { 773 774 if ( ! this.itemDataObject.elementorContent ) { 775 this.getElementorTemplate(); 776 } else { 777 778 jetMenu.eventBus.$emit( 'showTemplateContent', { 779 menuUniqId: this.menuOptions.menuUniqId, 780 id: this.itemDataObject.id, 781 name: this.itemDataObject.name, 782 elementorContent: this.itemDataObject.elementorContent 783 } ); 784 } 785 } 786 }, 787 788 getElementorTemplate: function() { 789 var vueInstance = this; 790 791 vueInstance.ajaxRequest = $.ajax( { 792 type: 'GET', 793 url: window.jetMenuPublicSettings.templateApiUrl, 794 dataType: 'json', 795 data: { 796 'id': vueInstance.itemDataObject.elementorTemplateId, 797 'dev': window.jetMenuPublicSettings.devMode 798 }, 799 beforeSend: function( jqXHR, ajaxSettings ) { 800 801 if ( null !== vueInstance.ajaxRequest ) { 802 vueInstance.ajaxRequest.abort(); 803 } 804 805 vueInstance.templateLoadStatus = true; 806 }, 807 success: function( responce, textStatus, jqXHR ) { 808 var templateContent = responce['template_content'], 809 templateScripts = responce['template_scripts'], 810 templateStyles = responce['template_styles']; 811 812 for ( var scriptHandler in templateScripts ) { 813 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 814 } 815 816 for ( var styleHandler in templateStyles ) { 817 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 818 } 819 820 vueInstance.templateLoadStatus = false; 821 822 vueInstance.itemDataObject.elementorContent = templateContent; 823 824 jetMenu.eventBus.$emit( 'showTemplateContent', {
825 menuUniqId: vueInstance.menuOptions.menuUniqId, 826 id: vueInstance.itemDataObject.id, 827 name: vueInstance.itemDataObject.name, 828 elementorContent: vueInstance.itemDataObject.elementorContent 829 } ); 830 } 831 } ); 832 } 833 } 834 835 }); 836 837 Vue.component( 'mobilemenulist', { 838 template: '#mobile-menu-list-template', 839 840 props: { 841 depth: Number, 842 childrenObject: Object, 843 menuOptions: Object 844 } 845 846 }); 847 848 Vue.component( 'mobilemenu', { 849 template: '#mobile-menu-template', 850 851 props: { 852 menuOptions: { 853 type: Object, 854 default: {} 855 }, 856 }, 857 858 data: function() { 859 return ( { 860 menuOpen: false, 861 children: false, 862 itemsRawData: {}, 863 trail:[], 864 breadcrumbsData:[], 865 animation: 'items-next-animation', 866 ajaxRequest: null, 867 templateVisible: false, 868 instanceLoadStatus: false, 869 itemTemplateContent: false, 870 871 headerTemplate: this.menuOptions['headerTemplate'] || 0, 872 headerContent: false, 873 headerTemplateVisible: false, 874 beforeTemplate: this.menuOptions['beforeTemplate'] || 0, 875 beforeContent: false, 876 afterTemplate: this.menuOptions['afterTemplate'] || 0, 877 afterContent: false, 878 879 ajaxPromises: [] 880 } ) 881 }, 882 883 mounted: function() { 884 let vueInstance = this; 885 886 if ( this.menuOpen ) { 887 jetMenu.$body.addClass( 'jet-mobile-menu-visible' ); 888 } 889 890 this.ajaxPromises.push( 891 new Promise( function( resolve, reject ) { 892 $.ajax( { 893 type: 'GET', 894 url: window.jetMenuPublicSettings.menuItemsApiUrl, 895 dataType: 'json', 896 data: { 897 'menu_id': vueInstance.menuId, 898 'dev': window.jetMenuPublicSettings.devMode 899 }, 900 beforeSend: function( jqXHR, ajaxSettings ) { 901 902 }, 903 success: function( responce, textStatus, jqXHR ) { 904 let responceData = responce.data.items; 905 906 vueInstance.itemsRawData = responceData; 907 908 resolve(); 909 } 910 } ); 911 } ) 912 ); 913 914 if ( 0 !== +this.headerTemplate ) { 915 this.ajaxPromises.push( 916 new Promise( function( resolve, reject ) { 917 $.ajax( { 918 type: 'GET', 919 url: window.jetMenuPublicSettings.templateApiUrl, 920 dataType: 'json', 921 data: { 922 'id': vueInstance.headerTemplate, 923 'dev': window.jetMenuPublicSettings.devMode 924 }, 925 success: function( responce, textStatus, jqXHR ) { 926 let templateContent = responce['template_content'], 927 templateScripts = responce['template_scripts'], 928 templateStyles = responce['template_styles']; 929 930 for ( let scriptHandler in templateScripts ) { 931 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 932 } 933 934 for ( let styleHandler in templateStyles ) { 935 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 936 } 937 938 vueInstance.headerContent = templateContent; 939 vueInstance.headerTemplateVisible = true; 940 941 resolve(); 942 } 943 } ); 944 } ) 945 ); 946 } 947 948 if ( 0 !== +this.beforeTemplate ) { 949 this.ajaxPromises.push( 950 new Promise( function( resolve, reject ) { 951 $.ajax( { 952 type: 'GET', 953 url: window.jetMenuPublicSettings.templateApiUrl, 954 dataType: 'json', 955 data: { 956 'id': vueInstance.beforeTemplate, 957 'dev': window.jetMenuPublicSettings.devMode 958 }, 959 success: function( responce, textStatus, jqXHR ) { 960 let templateContent = responce['template_content'], 961 templateScripts = responce['template_scripts'], 962 templateStyles = responce['template_styles']; 963 964 for ( let scriptHandler in templateScripts ) { 965 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 966 } 967 968 for ( let styleHandler in templateStyles ) { 969 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 970 } 971 972 vueInstance.beforeContent = templateContent; 973 974 resolve(); 975 } 976 } ); 977 } ) 978 ); 979 } 980 981 if ( 0 !== +this.afterTemplate ) { 982 this.ajaxPromises.push( 983 new Promise( function( resolve, reject ) { 984 $.ajax( { 985 type: 'GET', 986 url: window.jetMenuPublicSettings.templateApiUrl, 987 dataType: 'json', 988 data: { 989 'id': vueInstance.afterTemplate, 990 'dev': window.jetMenuPublicSettings.devMode 991 }, 992 success: function( responce, textStatus, jqXHR ) { 993 let templateContent = responce['template_content'], 994 templateScripts = responce['template_scripts'], 995 templateStyles = responce['template_styles']; 996 997 for ( let scriptHandler in templateScripts ) { 998 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 999 } 1000 1001 for ( let styleHandler in templateStyles ) { 1002 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 1003 } 1004 1005 vueInstance.afterContent = templateContent; 1006 resolve(); 1007 } 1008 } ); 1009 } ) 1010 ); 1011 } 1012 1013 this.instanceLoadStatus = true; 1014 1015 Promise.all( this.ajaxPromises ).then( function() { 1016 vueInstance.instanceLoadStatus = false;
1017 }, function( reason ) { 1018 console.log( 'Script Loaded Error' ); 1019 } ); 1020 1021 jetMenu.eventBus.$on( 'itemsSubSwitch', function ( payLoad ) { 1022 1023 if ( vueInstance.menuOptions.menuUniqId !== payLoad.menuUniqId ) { 1024 return; 1025 } 1026 1027 vueInstance.trail.push( payLoad.children ); 1028 vueInstance.children = payLoad.children; 1029 vueInstance.breadcrumbsData.push( payLoad.name ); 1030 vueInstance.animation = 'items-next-animation'; 1031 } ); 1032 1033 jetMenu.eventBus.$on( 'showTemplateContent', function ( payLoad ) { 1034 1035 if ( vueInstance.menuOptions.menuUniqId !== payLoad.menuUniqId ) { 1036 return; 1037 } 1038 1039 vueInstance.itemTemplateContent = payLoad.elementorContent; 1040 vueInstance.templateVisible = true; 1041 vueInstance.breadcrumbsData.push( payLoad.name ); 1042 vueInstance.animation = 'items-next-animation'; 1043 1044 vueInstance.showTemplateContent(); 1045 } ); 1046 1047 }, 1048 1049 computed: { 1050 instanceClass: function() { 1051 let classes = [ 1052 `jet-mobile-menu__instance--${ this.menuOptions.menuLayout }-layout`, 1053 `${ this.menuOptions.menuPosition }-container-position`, 1054 `${ this.menuOptions.togglePosition || 'default' }-toggle-position`, 1055 ]; 1056 1057 return classes; 1058 }, 1059 1060 menuId: function() { 1061 1062 if ( this.menuOptions.mobileMenuId ) { 1063 return this.menuOptions.mobileMenuId; 1064 } 1065 1066 return this.menuOptions.menuId; 1067 }, 1068 1069 coverVisible: function() { 1070 1071 let avaliableForLayout = [ 1072 'slide-out' 1073 ]; 1074 1075 return avaliableForLayout.includes( this.menuOptions.menuLayout ); 1076 }, 1077 1078 itemsList: function() { 1079 1080 if ( ! this.children ) { 1081 return this.itemsRawData; 1082 } 1083 1084 return this.children; 1085 }, 1086 1087 isClose: function() { 1088 let avaliableForLayout = [ 1089 'slide-out' 1090 ]; 1091 1092 return avaliableForLayout.includes( this.menuOptions.menuLayout ); 1093 }, 1094 1095 isBack: function() { 1096 return this.children || this.templateVisible ? true : false; 1097 }, 1098 1099 isBreadcrumbs: function() { 1100 return this.menuOptions.useBreadcrumb && 0 !== this.breadcrumbsData.length ? true : false; 1101 }, 1102 1103 depth: function() { 1104 return this.trail.length; 1105 }, 1106 1107 containerPosition: function() { 1108 return this.menuOptions['menuPosition']; 1109 }, 1110 1111 showAnimation: function() { 1112 1113 let animation = false; 1114 1115 switch( this.menuOptions.menuLayout ) { 1116 1117 case 'slide-out': 1118 animation = 'right' === this.containerPosition ? 'menu-container-left-animation' : 'menu-container-right-animation'; 1119 break; 1120 1121 case 'dropdown': 1122 animation = 'menu-container-dropdown-animation'; 1123 break; 1124 1125 case 'push': 1126 animation = 'menu-container-expand-animation'; 1127 break; 1128 } 1129 1130 return animation; 1131 }, 1132 1133 toggleClosedIcon: function() { 1134 return '' !== this.menuOptions.toggleClosedIcon ? this.menuOptions.toggleClosedIcon : '<i class="fas fa-bars"></i>'; 1135 }, 1136 1137 toggleOpenedIcon: function() { 1138 return '' !== this.menuOptions.toggleOpenedIcon ? this.menuOptions.toggleOpenedIcon : '<i class="fas fa-times"></i>'; 1139 }, 1140 1141 toggleText: function() { 1142 return '' !== this.menuOptions.toggleText ? this.menuOptions.toggleText : false; 1143 }, 1144 1145 closeIcon: function() { 1146 return '' !== this.menuOptions.closeIcon ? this.menuOptions.closeIcon : '<i class="fas fa-times"></i>'; 1147 }, 1148 1149 backIcon: function() { 1150 let backIcon = '' !== this.menuOptions.backIcon ? this.menuOptions.backIcon : '<i class="fas fa-arrow-left"></i>', 1151 backText = '' !== this.menuOptions.backText ? `<span>${ this.menuOptions.backText }</span>` : '', 1152 backHtml = backIcon + backText; 1153 1154 return backHtml; 1155 }, 1156 1157 backText: function() { 1158 return '' !== this.menuOptions.backText ? this.menuOptions.backText : false; 1159 }, 1160 1161 breadcrumbIcon: function() { 1162 return '' !== this.menuOptions.breadcrumbIcon ? this.menuOptions.breadcrumbIcon : '<i class="fas fa-angle-rightt"></i>'; 1163 }, 1164 1165 loaderColor: function() { 1166 return this.menuOptions.loaderColor || '#3a3a3a'; 1167 }, 1168 1169 toggleLoaderVisible: function() { 1170 return this.menuOptions.toggleLoader && this.instanceLoadStatus ? true : false;
1171 }, 1172 1173 beforeTemplateVisible: function() { 1174 return this.beforeContent ? true : false; 1175 }, 1176 1177 afterTemplateVisible: function() { 1178 return this.afterContent ? true : false; 1179 } 1180 1181 }, 1182 1183 watch: { 1184 menuOpen: function( curr, prev ) { 1185 1186 if ( curr ) { 1187 jetMenu.$body.addClass( 'jet-mobile-menu-visible' ); 1188 1189 this.initTemplatesContent(); 1190 } 1191 1192 if ( ! curr ) { 1193 jetMenu.$body.removeClass( 'jet-mobile-menu-visible' ); 1194 this.clearStates(); 1195 } 1196 } 1197 }, 1198 1199 methods: { 1200 menuToggle: function() { 1201 this.menuOpen = ! this.menuOpen; 1202 }, 1203 1204 closeMenu: function() { 1205 this.menuOpen = false; 1206 }, 1207 1208 clearStates: function() { 1209 this.trail = []; 1210 this.children = false; 1211 this.breadcrumbsData = []; 1212 this.templateVisible = false; 1213 }, 1214 1215 goBack: function() { 1216 1217 this.animation = 'items-prev-animation'; 1218 1219 if ( ! this.templateVisible ) { 1220 this.$delete( this.trail, this.trail.length - 1 ); 1221 this.children = this.trail.slice(-1)[0] || false; 1222 } else { 1223 this.templateVisible = false; 1224 } 1225 1226 this.$delete(this.breadcrumbsData, this.breadcrumbsData.length - 1); 1227 }, 1228 1229 showTemplateContent: function() { 1230 let vueInstance = this; 1231 1232 this.$nextTick( function() { 1233 let $templateContainer = $( vueInstance.$refs['template-content'] ).find( '.jet-mobile-menu__template-content' ); 1234 1235 jetMenu.elementorContentRender( $templateContainer ); 1236 } ); 1237 }, 1238 1239 initTemplatesContent: function() { 1240 let vueInstance = this; 1241 1242 this.$nextTick( function() { 1243 1244 if ( vueInstance.headerContent ) { 1245 let $headerContainer = $( vueInstance.$refs['header-template-content'] ); 1246 1247 jetMenu.elementorContentRender( $headerContainer ); 1248 } 1249 1250 if ( vueInstance.beforeContent ) { 1251 let $beforeContainer = $( vueInstance.$refs['before-template-content'] ); 1252 1253 jetMenu.elementorContentRender( $beforeContainer ); 1254 } 1255 1256 if ( vueInstance.beforeContent ) { 1257 let $afterContainer = $( vueInstance.$refs['after-template-content'] ); 1258 1259 jetMenu.elementorContentRender( $afterContainer ); 1260 } 1261 } ); 1262 }, 1263 1264 breadcrumbHandle: function( index ) { 1265 1266 if ( index === this.breadcrumbsData.length ) { 1267 return; 1268 } 1269 1270 this.animation = 'items-prev-animation'; 1271 1272 this.trail = this.trail.slice( 0, index ); 1273 this.children = this.trail.slice( -1 )[0] || false; 1274 this.templateVisible = false; 1275 this.breadcrumbsData = this.breadcrumbsData.slice( 0, index ); 1276 } 1277 1278 } 1279 }); 1280 }, 1281 1282 loadScriptAsync: function( script, uri ) { 1283 1284 if ( jetMenu.addedScripts.hasOwnProperty( script ) ) { 1285 return script; 1286 } 1287 1288 jetMenu.addedScripts[ script ] = uri; 1289 1290 return new Promise( function( resolve, reject ) { 1291 var tag = document.createElement( 'script' ); 1292 1293 tag.src = uri; 1294 tag.async = true; 1295 tag.onload = function() { 1296 resolve( script ); 1297 }; 1298 1299 document.head.appendChild( tag ); 1300 } ); 1301 }, 1302 1303 loadStyle: function( style, uri ) { 1304 1305 if ( jetMenu.addedStyles.hasOwnProperty( style ) && jetMenu.addedStyles[ style ] === uri) { 1306 return style; 1307 } 1308 1309 jetMenu.addedStyles[ style ] = uri; 1310 1311 return new Promise( function( resolve, reject ) { 1312 var tag = document.createElement( 'link' ); 1313 1314 tag.id = style; 1315 tag.rel = 'stylesheet'; 1316 tag.href = uri; 1317 tag.type = 'text/css'; 1318 tag.media = 'all'; 1319 tag.onload = function() { 1320 resolve( style ); 1321 }; 1322 1323 document.head.appendChild( tag ); 1324 }); 1325 }, 1326 1327 elementorContentRender: function( $templateContainer, templateContent ) { 1328 let content = templateContent || false; 1329 1330 Promise.all( jetMenu.addedAssetsPromises ).then( function( value ) { 1331 1332 if ( templateContent ) { 1333 $templateContainer.html( templateContent ); 1334 } 1335 1336 jetMenu.elementorFrontendInit( $templateContainer ); 1337 }, function( reason ) { 1338 console.log( 'Script Loaded Error' ); 1339 }); 1340 }, 1341 1342 elementorFrontendInit: function( $templateContainer ) { 1343 1344 $templateContainer.find( 'div[data-element_type]' ).each( function() { 1345 var $this = $( this ), 1346 elementType = $this.data( 'element_type' ); 1347 1348 if ( ! elementType ) { 1349 return; 1350 } 1351 1352 try { 1353 if ( 'widget' === elementType ) { 1354 elementType = $this.data( 'widget_type' ); 1355 1356 if ( window.elementorFrontend && window.elementorFrontend.hooks ) { 1357 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 1358 } 1359 } 1360 1361 if ( window.elementorFrontend && window.elementorFrontend.hooks ) { 1362 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 1363 } 1364 1365 } catch ( err ) { 1366 console.log(err); 1367 1368 $this.remove(); 1369 1370 return false;
1371 } 1372 } ); 1373 } 1374 1375 }; 1376 1377 jetMenu.init(); 1378 1379} ( 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.