1( function( $ ) { 2 'use strict'; 3 4 /** 5 * JetMegaMenuClass 6 */ 7 class JetMegaMenuClass { 8 9 /** 10 * [constructor description] 11 * @return {[type]} [description] 12 */ 13 constructor( instance, options ) { 14 this.defaultSettings = { 15 menuId: '0', 16 menuUniqId: window.jetMenu.getUniqId(), 17 layout: 'horizontal', 18 subTrigger: 'item', // item, submarker 19 subEvent: 'click', // hover, click 20 rollUp: true, 21 breakpoint: 768, // Minimal menu width, when this plugin activates 22 mouseLeaveDelay: 500, 23 megaWidthType: 'container', 24 megaWidthSelector: '', 25 megaAjaxLoad: false, 26 classes: { 27 instance: 'menu', 28 menuContainer: 'menu-container', 29 menuList: 'menu-list', 30 menuItem: 'menu-item', 31 menuItemLink: 'menu-item__link', 32 subMenuContainer: 'sub-menu', 33 subMenuList: 'sub-menu__list', 34 megaContainer: 'mega-container', 35 } 36 } 37 38 this.$instance = $( instance ); 39 this.settings = $.extend( this.defaultSettings, options ); 40 this.$window = $( window ); 41 this.$document = $( document ); 42 this.$body = $( 'body' ); 43 this.isRTL = this.$body.hasClass( 'rtl' ); 44 this.isDropdownState = false; 45 46 this.createInstance(); 47 } 48 49 createInstance() { 50 this.$menuList = $( `.${ this.settings.classes.menuList }`, this.$instance ); 51 this.$menuItems = $( `>.${ this.settings.classes.menuItem }:not(.${ this.settings.classes.menuItem }--roll-up)`, this.$menuList ); 52 this.$rollUpItem = $( `>.${ this.settings.classes.menuItem }--roll-up`, this.$menuList ); 53 54 this.menuItemsData = this.$menuItems.toArray().map( function( item ) { 55 return { 56 element: item, 57 outerWidth: $( item ).outerWidth( true ), 58 offsetLeft: $( item )[0].offsetLeft, 59 } 60 } ); 61 62 this.initWatcher( 50 ); 63 this.initEvents(); 64 this.maybeRollUpItems(); 65 this.rebuildSubContainers(); 66 this.watchTick(); 67 68 document.addEventListener( 'DOMContentLoaded', ( event ) => { 69 setTimeout( () => { 70 this.watchTick(); 71 }, 250 ); 72 } ); 73 74 this.$instance.addClass( `${ this.settings.classes.instance }--inited` ); 75 this.$document.trigger( 'JetMegaMenuInited' ); 76 } 77 78 initEvents() { 79 let debounceTimer, 80 eventHandler = 'JetMegaMenu', 81 $itemTargetSelector = 'item' === this.settings.subTrigger ? `.${ this.settings.classes.menuItem } > .${ this.settings.classes.menuItem }__inner` : `.${ this.settings.classes.menuItem } > .${ this.settings.classes.menuItem }__inner .${ this.settings.classes.menuItem }__dropdown`; 82 83 switch ( this.settings.subEvent ) { 84 case 'hover': 85 this.$instance.on( `mouseenter.${ eventHandler }`, `.${ this.settings.classes.menuItem } > .${ this.settings.classes.menuItem }__inner`, { instance: this }, ( event ) => { 86 let $target = $( event.target ), 87 $menuItem = $target.parents( `.${ this.settings.classes.menuItem }` ), 88 $subContainer = $( `.${ this.settings.classes.subMenuContainer }:first, .${ this.settings.classes.megaContainer }:first`, $menuItem ), 89 templateContent = $subContainer.data( 'template-content' ) || false, 90 templateId = $subContainer.data( 'template-id' ) || false; 91 92 $( `.${ this.settings.classes.menuItem }--hover`, this.$instance ).removeClass( `${ this.settings.classes.menuItem }--hover` ); 93 94 if ( $menuItem.hasClass( `${ this.settings.classes.menuItem }-has-children` ) ) { 95 $menuItem.addClass( `${ this.settings.classes.menuItem }--hover` ); 96 97 if ( templateId ) { 98 this.maybeTemplateLoad( templateId, templateContent, $subContainer ); 99 } 100 } 101 } ); 102 103 this.$instance.on( `mouseleave.${ eventHandler }`, `.${ this.settings.classes.menuItem } > .${ this.settings.classes.menuItem }__inner`, ( event ) => { /* Item Mouse Leave Event */ } ); 104 break; 105 106 case 'click': 107 108 this.$instance.on( `click.${ eventHandler }`, $itemTargetSelector, ( event ) => { 109 event.preventDefault(); 110 event.stopPropagation(); 111 112 let $currentTarget = $( event.currentTarget ), 113 $menuItem = $currentTarget.closest( `.${this.settings.classes.menuItem}` ), 114 $menuItemLink = $( '.jet-mega-menu-item__link', $menuItem ).first(), 115 $siblingsItems = $menuItem.siblings( `.${this.settings.classes.menuItem}-has-children` ), 116 $subContainer = $( `.${this.settings.classes.subMenuContainer}:first, .${this.settings.classes.megaContainer}`, $menuItem ), 117 templateContent = $subContainer.data( 'template-content' ) || false, 118 templateId = $subContainer.data( 'template-id' ) || false; 119 120 if ( $siblingsItems.length ) { 121 $siblingsItems.removeClass( `${ this.settings.classes.menuItem }--hover` ); 122 $( `.${ this.settings.classes.menuItem }-has-children`, $siblingsItems ).removeClass( `${ this.settings.classes.menuItem }--hover` ); 123 } 124 125 if ( $menuItem.hasClass( `${ this.settings.classes.menuItem }-has-children` ) ) { 126 if ( ! $menuItem.hasClass( `${ this.settings.classes.menuItem }--hover` ) ) { 127 $menuItem.addClass( `${ this.settings.classes.menuItem }--hover` ); 128 } else { 129 $menuItem.removeClass( `${ this.settings.classes.menuItem }--hover` ); 130 } 131 132 if ( templateId ) { 133 this.maybeTemplateLoad( templateId, templateContent, $subContainer ); 134 } 135 } else { 136 let itemLink = $menuItemLink.attr( 'href' ) || '#', 137 target = $menuItemLink.attr( 'target' ) || '_self'; 138 139 window.open( itemLink, target ); 140 141 return false;
142 } 143 } ); 144 break; 145 } 146 147 this.$instance.on( `mouseenter.${ eventHandler }`, `.${ this.settings.classes.subMenuContainer }, .${ this.settings.classes.megaContainer }`, ( event ) => { 148 clearTimeout( debounceTimer ); 149 } ); 150 151 this.$instance.on( `mouseenter.${ eventHandler }`, ( event ) => { 152 clearTimeout( debounceTimer ); 153 } ); 154 155 this.$instance.on( `mouseleave.${ eventHandler }`, ( event ) => { 156 debounceTimer = setTimeout( () => { 157 $( `.${ this.settings.classes.menuItem }--hover`, this.$instance ).removeClass( `${ this.settings.classes.menuItem }--hover` ); 158 }, this.settings.mouseLeaveDelay ); 159 } ); 160 161 this.$window.on( `orientationchange.${ eventHandler } resize.${ eventHandler }`, ( event ) => { 162 $( `.${ this.settings.classes.menuItem }`, this.$instance ).removeClass( `${ this.settings.classes.menuItem }--hover` ); 163 this.$instance.removeClass( `${ this.settings.classes.instance }--dropdown-open` ); 164 } ); 165 166 this.$document.on( `touchend.${ eventHandler }`, ( event ) => { 167 168 if ( $( event.target ).closest( `.${ this.settings.classes.menuItem }` ).length ) { 169 return; 170 } 171 172 $( `.${ this.settings.classes.menuItem }`, this.$instance ).removeClass( `${ this.settings.classes.menuItem }--hover` ); 173 } ); 174 175 this.$instance.on( 'watchTickEventResetRegularState', ( event ) => { 176 this.resetRegularState(); 177 178 if ( this.$rollUpItem[0] ) { 179 $( `.${ this.settings.classes.subMenuList }:first`, this.$rollUpItem ).empty(); 180 this.$rollUpItem[0].hidden = true; 181 } 182 183 for ( let index = 0; index < this.menuItemsData.length; index++ ) { 184 this.menuItemsData[ index ].element.hidden = false; 185 } 186 } ); 187 188 this.$instance.on( 'watchTickEventResetDropdownState', ( event ) => { 189 this.resetDropdownState(); 190 this.$instance.removeClass( `${ this.settings.classes.instance }--dropdown-open` ); 191 } ); 192 193 this.$instance.on( `click.${ eventHandler }`, `.${ this.settings.classes.instance }-toggle`, ( event ) => { 194 195 if ( ! this.$instance.hasClass( `${ this.settings.classes.instance }--dropdown-open` ) ) { 196 this.$instance.addClass( `${ this.settings.classes.instance }--dropdown-open` ); 197 } else { 198 this.$instance.removeClass( `${ this.settings.classes.instance }--dropdown-open` ); 199 } 200 } ); 201 202 } 203 204 /** 205 * Init watcher function. 206 * 207 * @param {number} Watcher debounce delay. 208 * @return {void} 209 */ 210 initWatcher( delay = 10 ) { 211 $( window ).off( `resize.JetMegaMenu${ this.settings['menuUniqId'] }` ).on( `resize.JetMegaMenu${ this.settings['menuUniqId'] } orientationchange.JetMegaMenu${ this.settings['menuUniqId'] }`, this.debounce( delay, this.watchTick.bind( this ) ) ); 212 this.$instance.trigger( 'containerResize' ); 213 } 214 215 /** 216 * Responsive menu watcher callback. 217 * 218 * @param {Object} Resize or Orientationchange event. 219 * @return {void} 220 */ 221 watchTick( event ) { 222 223 if ( this.isDropdown() ) { 224 225 if ( ! this.isDropdownState ) { 226 this.$instance.trigger( 'watchTickEventResetRegularState' ); 227 } 228 229 this.isDropdownState = true; 230 this.$instance.removeClass( `${ this.settings.classes.instance }--layout-horizontal ${ this.settings.classes.instance }--layout-vertical` ); 231 this.$instance.addClass( `${ this.settings.classes.instance }--layout-dropdown` ); 232 this.$instance.trigger( 'watchTickEventDropdown' ); 233 } else { 234 235 if ( this.isDropdownState ) { 236 this.$instance.trigger( 'watchTickEventResetDropdownState' ); 237 } 238 239 this.isDropdownState = false; 240 this.$instance.removeClass( `${ this.settings.classes.instance }--layout-dropdown` ); 241 this.$instance.addClass( `${ this.settings.classes.instance }--layout-${ this.settings.layout }` ); 242 this.$instance.trigger( `watchTickEventRegular` ); 243 this.$instance.trigger( `watchTickEventRegular--${ this.settings.layout }` ); 244 } 245 246 this.$instance.trigger( 'watchTickEvent' ); 247 } 248 249 /** 250 * Rollup rebuilding function. 251 * 252 * @return {void} 253 */ 254 maybeRollUpItems() { 255 this.$instance.on( 'watchTickEventRegular--horizontal', ( event ) => { 256 257 if ( ! this.settings.rollUp ) { 258 return false;
259 } 260 261 let mainMenuWidth = this.$instance.width(), 262 visibleItemsArray = [], 263 hiddenItemsArray = []; 264 265 for ( let index = 0; index < this.menuItemsData.length; index++ ) { 266 let itemData = this.menuItemsData[ index ], 267 nextItemData = this.menuItemsData[ index + 1 ] || false, 268 offsetLeft = nextItemData ? nextItemData.offsetLeft : itemData.offsetLeft + itemData.outerWidth, 269 item = itemData.element; 270 271 if ( offsetLeft + this.$rollUpItem.outerWidth( true ) > mainMenuWidth ) { 272 item.hidden = true; 273 hiddenItemsArray.push( item ); 274 } else { 275 item.hidden = false; 276 visibleItemsArray.push( item ); 277 } 278 } 279 280 $( `.${ this.settings.classes.subMenuList }:first`, this.$rollUpItem ).empty(); 281 282 for ( let hiddenMenuItem of hiddenItemsArray ) { 283 let $hiddenClone = $( hiddenMenuItem ).clone(); 284 285 $hiddenClone[0].hidden = false; 286 287 $( `>.${ this.settings.classes.menuItem }__inner >.${ this.settings.classes.menuItemLink }`, $hiddenClone ).toggleClass( `${ this.settings.classes.menuItemLink }--top-level ${ this.settings.classes.menuItemLink }--sub-level` ); 288 $( `.${ this.settings.classes.subMenuList }:first`, this.$rollUpItem ).append( $hiddenClone ); 289 } 290 291 if ( this.$rollUpItem[0] ) { 292 this.$rollUpItem[0].hidden = hiddenItemsArray.length ? false : true; 293 } 294 295 this.$instance.trigger( 'rollUpItemsEvent' ); 296 } ) 297 } 298 299 /** 300 * Rebuild SubContainers function. 301 * 302 * @return {void} 303 */ 304 rebuildSubContainers() { 305 this.$instance.on( 'watchTickEventRegular--horizontal', ( event ) => { 306 let $megaMenuList = $( `.${ this.settings.classes.megaContainer }`, this.$instance ), 307 $subMenuList = $( `.${ this.settings.classes.subMenuContainer }`, this.$instance ), 308 subInverseClass = `${ this.settings.classes.subMenuContainer }--inverse`, 309 instanceWidth = this.$instance.width(), 310 instanceOffset = this.$instance.offset(); 311 312 $subMenuList.each( ( index, element ) => { 313 let $element = $( element ); 314 315 if ( this.isOffscreenX( element ) ) { 316 $element.addClass( subInverseClass ); 317 } else { 318 $element.removeClass( subInverseClass ); 319 } 320 } ); 321 322 switch( this.settings.megaWidthType ) { 323 case 'container': 324 $megaMenuList.each( ( index, element ) => { 325 let $element = $( element ), 326 $elementPosition = $element.data( 'position' ), 327 elementOffset = $element.offset(), 328 elementDeltaOffset = 'default' === $elementPosition ? Math.ceil( instanceOffset.left - elementOffset.left ) : 0; 329 330 $element.css( { 331 '--jmm-submenu-width': `${ instanceWidth }px`, 332 '--jmm-submenu-delta-x-offset': `${ elementDeltaOffset }px` 333 } ); 334 } ); 335 336 break; 337 case 'selector': 338 let $customSelector = $( this.settings.megaWidthSelector ); 339 340 if ( $customSelector[0] ) { 341 let selectorWidth = $customSelector.width(), 342 selectorOffset = Math.round( $customSelector.offset().left ); 343 344 document.fonts.ready.then( () => { 345 $megaMenuList.each( ( index, element ) => { 346 let $element = $( element ), 347 $elementPosition = $element.data( 'position' ), 348 elementOffset = Math.round( $element.offset().left ), 349 elementDeltaOffset = 'default' === $elementPosition ? Math.round( selectorOffset - elementOffset ) : 0; 350 351 $element.css( { 352 '--jmm-submenu-width': `${ selectorWidth }px`, 353 '--jmm-submenu-delta-x-offset': `${ elementDeltaOffset }px` 354 } ); 355 } ); 356 } ); 357 358 } 359 360 break; 361 case 'items': 362 let $lastItem = $( `.${ this.settings.classes.menuItem }--top-level:not([hidden]):last`, this.$instance ), 363 $firstItem = $( `.${ this.settings.classes.menuItem }--top-level:not([hidden]):first`, this.$instance ), 364 lastItemBounding = $lastItem[0].getBoundingClientRect(), 365 firstItemBounding = $firstItem[0].getBoundingClientRect(), 366 itemsWidth = lastItemBounding.x + lastItemBounding.width - firstItemBounding.x; 367 368 $megaMenuList.each( ( index, element ) => { 369 let $element = $( element ), 370 $elementPosition = $element.data( 'position' ), 371 elementOffset = $element.offset(), 372 elementDeltaOffset = 'default' === $elementPosition ? Math.ceil( instanceOffset.left - elementOffset.left ) : 0; 373 374 $element.css( { 375 '--jmm-submenu-width': `${ itemsWidth }px`, 376 '--jmm-submenu-delta-x-offset': `${ elementDeltaOffset }px` 377 } ); 378 } ); 379 break; 380 } 381 } ); 382
383 this.$instance.on( 'watchTickEventRegular--vertical', ( event ) => { 384 let $megaMenuList = $( `.${ this.settings.classes.megaContainer }`, this.$instance ), 385 $subMenuList = $( `.${ this.settings.classes.subMenuContainer }`, this.$instance ), 386 instanceWidth = this.$instance.width(), 387 instanceHeight = this.$instance.height(), 388 instanceOffset = this.$instance.offset(), 389 windowWidth = this.$window.outerWidth( true ), 390 subInverseClass = `${ this.settings.classes.subMenuContainer }--inverse`, 391 megaInverseClass = `${ this.settings.classes.megaContainer }--inverse`; 392 393 $subMenuList.each( ( index, element ) => { 394 let $element = $( element ); 395 396 if ( this.isOffscreenX( element ) ) { 397 $element.addClass( subInverseClass ); 398 } else { 399 $element.removeClass( subInverseClass ); 400 } 401 } ); 402 403 $megaMenuList.each( ( index, element ) => { 404 let $element = $( element ), 405 $elementPosition = $element.data( 'position' ), 406 $parentElement = $element.parent(), 407 elementOffset = $element.offset(), 408 elementDeltaOffsetX = ( instanceOffset.left - elementOffset.left ) + instanceWidth, 409 elementDeltaOffsetY = 'default' === $elementPosition ? ( instanceOffset.top - elementOffset.top ) : 0, 410 elementDeltaWidth = ( elementDeltaOffsetX + $element.width() ); 411 412 if ( $parentElement.hasClass(`${ this.settings.classes.menuItem }--top-level` ) ) { 413 $element.css( { 414 //'--jmm-submenu-width': `${ instanceWidth }px`, 415 '--jmm-submenu-min-height': `${ instanceHeight }px`, 416 //'--jmm-submenu-delta-x-offset': `${ elementDeltaOffsetX }px`, 417 '--jmm-submenu-delta-y-offset': `${ elementDeltaOffsetY }px` 418 } ); 419 } 420 421 if ( this.isOffscreenX( element ) ) { 422 $element.addClass( megaInverseClass ); 423 } else { 424 $element.removeClass( megaInverseClass ); 425 } 426 } ); 427 } ); 428 } 429 430 /** 431 * Reset Regular State 432 * 433 * @return {void} 434 */ 435 resetRegularState() {} 436 437 /** 438 * Reset Dropdown State 439 * 440 * @return {void} 441 */ 442 resetDropdownState() {} 443 444 /** 445 * Get mobile status. 446 * 447 * @return {boolean} Mobile Status 448 */ 449 isDropdown() { 450 return ( this.$window.width() < this.settings.breakpoint || 'dropdown' === this.settings.layout ) ? true : false; 451 } 452 453 /** 454 * 455 * @param element 456 * @returns {boolean} 457 */ 458 isOffscreenX( element ) { 459 let rect = element.getBoundingClientRect(); 460 461 return ( 462 rect.x < 0 || ( rect.x + rect.width ) > window.innerWidth 463 ); 464 } 465 466 /** 467 * Mobile and tablet check funcion. 468 * 469 * @return {boolean} Mobile Status 470 */ 471 mobileAndTabletcheck() { 472 let check = false; 473 474 (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 )|
474sy(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); 475 476 return check; 477 } 478 479 /** 480 * Debounce the function call 481 * 482 * @param {number} threshold The delay. 483 * @param {Function} callback The function. 484 */ 485 debounce( threshold, callback ) { 486 let timeout; 487 488 return function debounced( $event ) { 489 function delayed() { 490 callback.call( this, $event ); 491 timeout = null; 492 } 493 494 if ( timeout ) { 495 clearTimeout( timeout ); 496 } 497 498 timeout = setTimeout( delayed, threshold ); 499 }; 500 } 501 502 maybeTemplateLoad( templateId, templateContent, $templateContainer ) { 503 504 if ( ! this.settings.megaAjaxLoad ) { 505 return; 506 } 507 508 if ( $templateContainer.hasClass( 'template-loaded' ) ) { 509 return; 510 } 511 512 let getMegaContentUrl = 'default' === templateContent ? window.jetMenuPublicSettings.getBlocksTemplateApiUrl : window.jetMenuPublicSettings.getElementorTemplateApiUrl; 513 514 let signatures = this.settings['signatures']; 515 let signature = ''; 516 517 if ( signatures.hasOwnProperty(`template_${templateId}`) ) { 518 signature = signatures[`template_${templateId}`].signature; 519 } 520 521 $.ajax( { 522 type: 'GET', 523 url: getMegaContentUrl, 524 dataType: 'json', 525 data: { 526 'id': templateId, 527 'dev': window.jetMenuPublicSettings.devMode, 528 'signature': signature 529 }, 530 beforeSend: function( jqXHR, ajaxSettings ) { 531 jqXHR.setRequestHeader( 'X-WP-Nonce', window.jetMenuPublicSettings.restNonce ); 532 }, 533 success: function( responce, textStatus, jqXHR ) { 534 const {content, contentElements} = responce; 535 const templateData = { 536 content, 537 contentElements, 538 contentType: templateContent, 539 } 540 541 $templateContainer.addClass( 'template-loaded' ); 542 543 jetMenu.megaContentRender( $( '.jet-mega-menu-mega-container__inner', $templateContainer ), templateData ); 544 } 545 } ); 546 } 547 } 548 549 // jQuery plugin 550 $.fn.JetMegaMenu = function( options ) { 551 return this.each( function() { 552 let $this = $( this ), 553 pluginOptions = ( 'object' === typeof options ) ? options : {}; 554 555 if ( ! $this.data( 'JetMegaMenu' ) ) { 556 // create plugin instance (only if not exists) and expose the entire instance API 557 $this.data( 'JetMegaMenu', new JetMegaMenuClass( this, pluginOptions ) ); 558 } 559 } ); 560 }; 561} ( jQuery )); 562 563// JetMenu Public Scripts 564( function( $ ) { 565 'use strict'; 566 567 window.jetMenu = { 568 569 addedScripts: {}, 570 571 addedStyles: {}, 572 573 addedAssetsPromises: [], 574 575 initedMobileRenderInstance: [], 576 577 eventBus: new Vue(), 578 579 $body: $( 'body' ), 580 581 init: function() { 582 this.initLocationMenuRender(); 583 this.mobileVueComponents(); 584 this.initMobileRender(); 585 586 window.addEventListener( 'jetMenu/editor/templateRenderer/renderSuccess', ( event ) => { 587 this.initLocationMenuRender(); 588 this.mobileVueComponents(); 589 this.initMobileRender(); 590 }, false ); 591 592 $( window ).on( 'jet-menu/ajax/frontend-init', ( event, payload ) => { 593 594 switch ( payload.contentType ) { 595 case 'elementor': 596 jetMenu.maybeElementorFrontendInit( payload.$container ); 597 break; 598 case 'default': 599 jetMenu.maybeDefaultFrontendInit( payload ); 600 break 601 } 602 } ); 603 604 $( window ).on( 'jet-menu/ajax/frontend-init/after', ( event, payload ) => { 605 this.initLocationMenuRender(); 606 this.mobileVueComponents(); 607 this.initMobileRender(); 608 this.megaContentHandler(event, payload); 609 610 if ( window.elementorFrontend ) { 611 const elementorLazyLoad = new CustomEvent( "elementor/lazyload/observe" ); 612 document.dispatchEvent( elementorLazyLoad ); 613 } 614 } ); 615 616 wp.hooks.addAction( 'jet-plugins.frontend.element-ready.jet-menu.mega-menu', 'jet-popup', ( $popupContainer, contentType ) => { 617 this.initLocationMenuRender(); 618 this.mobileVueComponents(); 619 this.initMobileRender(); 620 } ); 621 622 // Init Vue for hamburger menu block in Gutenberg ( also on DOM change ) 623 if ( document.body.classList.contains( 'block-editor-page' ) ) { 624 const tryObserve = () => { 625 const target = document.querySelector( '.block-editor-block-list__layout' ); 626 627 if ( target ) { 628 const initedMenus = new Set(); 629 630 const observer = new MutationObserver( () => { 631 const menus = document.querySelectorAll( '.jet-mobile-menu--location-wp-nav' ); 632
633 menus.forEach( (menu) => { 634 const menuId = menu.getAttribute( 'id' ); 635 636 if ( menuId && ! initedMenus.has( menuId ) ) { 637 jetMenu.initMobileRender(); 638 initedMenus.add( menuId ); 639 } 640 641 }); 642 }); 643 644 observer.observe( target, { childList: true, subtree: true } ); 645 } else { 646 requestAnimationFrame( tryObserve ); 647 } 648 }; 649 650 requestAnimationFrame( tryObserve ); 651 } 652 653 }, 654 655 initLocationMenuRender: function() { 656 657 let $megaMenuList = $( '.jet-mega-menu--location-wp-nav' ); 658 659 if ( ! $megaMenuList[0] ) { 660 return false; 661 } 662 663 $megaMenuList.each( function() { 664 let $this = $( this ), 665 settings = $this.data( 'settings' ); 666 667 $this.JetMegaMenu( { 668 rollUp: settings.rollUp, 669 layout: settings.layout, 670 subTrigger: settings.subTrigger, 671 subEvent: settings.subEvent, 672 mouseLeaveDelay: settings.mouseLeaveDelay, 673 breakpoint: settings.breakpoint, 674 megaWidthType: settings.megaWidthType, 675 megaWidthSelector: settings.megaWidthSelector, 676 megaAjaxLoad: settings.megaAjaxLoad, 677 classes: { 678 instance: 'jet-mega-menu', 679 menuContainer: 'jet-mega-menu-container', 680 menuList: 'jet-mega-menu-list', 681 menuItem: 'jet-mega-menu-item', 682 menuItemLink: 'jet-mega-menu-item__link', 683 subMenuContainer: 'jet-mega-menu-sub-menu', 684 subMenuList: 'jet-mega-menu-sub-menu__list', 685 megaContainer: 'jet-mega-menu-mega-container', 686 } 687 } ); 688 } ); 689 }, 690 691 megaContentHandler: function(event, payload) { 692 const container = payload.$container[0]; 693 const mobileMenu = container.closest('.jet-mobile-menu'); 694 695 if ( ! mobileMenu ) { 696 return; 697 } 698 699 const { menuOptions } = mobileMenu.dataset; 700 const { menuUniqId } = JSON.parse( menuOptions ); 701 702 container.addEventListener('click', function (event) { 703 const link = event.target.closest('a'); 704 705 if (!link) { 706 return; 707 } 708 709 if (link.getAttribute('href')[0] !== '#') { 710 return; 711 } 712 713 window.jetMenu.eventBus.$emit('closeMenu', { 714 menuUniqId: menuUniqId, 715 }); 716 }); 717 }, 718 719 initMobileRender: function() { 720 721 let mobileMenuList = $( '.jet-mobile-menu--location-wp-nav' ); 722 723 if ( ! mobileMenuList[0] ) { 724 return false; 725 } 726 727 if ( 'true' === window.jetMenuPublicSettings.devMode ) { 728 Vue.config.devtools = true; 729 } 730 731 mobileMenuList.each( function() { 732 let $this = $( this ), 733 menuInstanceId = $this.attr( 'id' ), 734 menuId = $this.data( 'menu-id' ) || false, 735 menuOptions = $this.data( 'menu-options' ) || {}; 736 737 jetMenu.createMobileRenderInstance( menuInstanceId, menuId, menuOptions ); 738 } ); 739 }, 740 741 createMobileRenderInstance: function( menuInstanceId, menuId, menuOptions ) { 742 743 if ( jetMenu.initedMobileRenderInstance.includes( menuInstanceId ) ) { 744 return; 745 } 746 747 jetMenu.initedMobileRenderInstance.push( menuInstanceId ); 748 749 let mobileRenderInstance = new Vue( { 750 el: '#' + menuInstanceId, 751 data: { 752 uniqId: menuInstanceId, 753 menuOptions: menuOptions, 754 refsHtml: {}, 755 }, 756 mounted: function() { 757 let refsHtml = {}; 758 759 for ( var ref in this.$refs ) { 760 Object.assign( refsHtml, { [ ref ]: this.$refs[ ref ].innerHTML } ); 761 } 762 763 this.refsHtml = refsHtml; 764 } 765 } ); 766 }, 767 768 mobileVueComponents: function() { 769 770 Vue.component( 'mobile-menu-item', { 771 template: '#mobile-menu-item-template', 772 773 props: { 774 itemDataObject: Object, 775 depth: Number 776 }, 777 778 data: function() { 779 return ( { 780 ajaxRequest: null, 781 templateLoadStatus: false, 782 subDropdownVisible: false 783 } ) 784 }, 785 786 computed: { 787 788 itemClasses: function() { 789 let itemClasses = [ 790 'jet-mobile-menu__item', 791 'jet-menu-item-' + this.itemDataObject.itemId, 792 'jet-mobile-menu__item--sub-trigger-' + ( this.$root.menuOptions.subTrigger || 'item' ), 793 ]; 794 795 let customClasses = this.itemDataObject.classes; 796 797 if ( 0 !== customClasses.length ) { 798 itemClasses = itemClasses.concat( customClasses ); 799 } 800 801 const { href } = window.location; 802 let pageURL = null; 803 804 if ( href.includes('?') ) { 805 pageURL = href.substring(0, href.indexOf('?')); 806 } else { 807 pageURL = href; 808 } 809 810 if ( pageURL === this.itemDataObject.url ) { 811 itemClasses.push( 'jet-mobile-menu__item--active' ); 812 } 813 814 return itemClasses; 815 }, 816 817 itemLinkClasses: function() {
818 let classes = [ 819 'mobile-link', 820 0 === this.depth ? 'mobile-top-level-link' : 'mobile-sub-level-link', 821 ]; 822 823 return classes; 824 }, 825 826 isСhildrenDefine: function() { 827 return this.itemDataObject.children ? true : false; 828 }, 829 830 isTemplateDefine: function() { 831 return false !== this.itemDataObject.megaTemplateId ? true : false; 832 }, 833 834 megaContentType: function() { 835 return this.itemDataObject.megaContentType; 836 }, 837 838 isAjaxLoadingEnabled: function() { 839 return this.$root.menuOptions.megaAjaxLoad === true; 840 }, 841 842 getTemplateUrl: function() { 843 return 'default' === this.megaContentType ? window.jetMenuPublicSettings.getBlocksTemplateApiUrl : window.jetMenuPublicSettings.getElementorTemplateApiUrl; 844 }, 845 846 isSub: function() { 847 return this.isСhildrenDefine || this.isTemplateDefine ? true : false; 848 }, 849 850 isTopLevel: function() { 851 return 0 === this.depth ? true : false; 852 }, 853 854 isDropdownLayout: function() { 855 return this.isSub && ! this.isTemplateDefine && 'dropdown' === this.$root.menuOptions.subOpenLayout; 856 }, 857 858 depthClass: function() { 859 return 0 === this.depth ? 'mobile-top-level-link' : 'mobile-sub-level-link'; 860 }, 861 862 dropdownIconHtml: function() { 863 let dropdownIcon = this.$root.refsHtml.dropdownIcon ? this.$root.refsHtml.dropdownIcon : '<span class="dashicons dashicons-arrow-right"></span>', 864 dropdownOpenedIcon = this.$root.refsHtml.dropdownOpenedIcon ? this.$root.refsHtml.dropdownOpenedIcon : '<span class="dashicons dashicons-arrow-down"></span>'; 865 866 if ( this.subDropdownVisible ) { 867 dropdownIcon = dropdownOpenedIcon; 868 } 869 870 return dropdownIcon; 871 }, 872 873 itemIconHtml: function() { 874 return this.itemDataObject.itemIcon; 875 }, 876 877 isIconVisible: function() { 878 let iconVisible = this.$root.menuOptions.itemIconVisible; 879 880 return ! iconVisible || '' === this.itemDataObject.itemIcon || ! this.itemDataObject.itemIcon ? false : true; 881 }, 882 883 isBadgeVisible: function() { 884 let badgeVisible = this.$root.menuOptions.itemBadgeVisible; 885 886 return false === badgeVisible || '' === this.itemDataObject.badgeContent || ! this.itemDataObject.badgeContent ? false : true; 887 }, 888 889 isLabelVisible: function() { 890 let labelVisible = ! this.itemDataObject.hideItemText; 891 892 return false === labelVisible || '' === this.itemDataObject.name || ! this.itemDataObject.name ? false : true; 893 }, 894 895 isDescVisible: function() { 896 let descVisible = this.$root.menuOptions.itemDescVisible; 897 898 return false === descVisible || '' === this.itemDataObject.description || ! this.itemDataObject.description ? false : true; 899 }, 900 901 loaderColor: function() { 902 return this.$root.menuOptions.loaderColor || '#3a3a3a'; 903 }, 904 }, 905 906 methods: { 907 itemSubHandler: function( event ) { 908 let target = event.target, 909 mobileLink = $( target ).closest( '.mobile-link' ); 910 911 if ( 'item' !== this.$root.menuOptions.subTrigger ) { 912 return; 913 } 914 915 if ( this.isSub && mobileLink ) { 916 event.preventDefault(); 917 } 918 919 if ( ! this.isSub && mobileLink && this.$root.menuOptions.closeAfterNavigate ) { 920 jetMenu.eventBus.$emit( 'closeMenu', { 921 menuUniqId: this.$root.menuOptions.menuUniqId, 922 } ); 923 } 924 925 this.switchToSub( event ); 926 }, 927 928 markerSubHandler: function( event ) { 929 930 if ( 'submarker' !== this.$root.menuOptions.subTrigger ) { 931 return; 932 } 933 934 this.switchToSub( event ); 935 }, 936 937 switchToSub: function( event ) { 938 939 if ( ! this.isSub ) { 940 return; 941 } 942 943 if ( ! this.isTemplateDefine ) { 944 945 if ( this.isDropdownLayout ) { 946 this.subDropdownVisible = !this.subDropdownVisible; 947 948 return; 949 } 950 951 jetMenu.eventBus.$emit( 'itemsSubSwitch', { 952 menuUniqId: this.$root.menuOptions.menuUniqId, 953 id: this.itemDataObject.id, 954 name: this.itemDataObject.name, 955 children: this.itemDataObject.children || false 956 } ); 957 } else { 958 if ( this.isAjaxLoadingEnabled && ! this.itemDataObject.megaContentLoaded ) { 959 this.getMegaTemplate(); 960 } else { 961 jetMenu.eventBus.$emit( 'showTemplateContent', {
962 menuUniqId: this.$root.menuOptions.menuUniqId, 963 id: this.itemDataObject.id, 964 name: this.itemDataObject.name, 965 megaContent: this.itemDataObject.megaContent, 966 megaContentType: this.itemDataObject.megaContentType, 967 } ); 968 } 969 } 970 }, 971 972 getMegaTemplate: function() { 973 var vueInstance = this; 974 975 if ( ! this.isAjaxLoadingEnabled ) { 976 return; 977 } 978 979 var signature = vueInstance.itemDataObject.signature || ''; 980 981 vueInstance.ajaxRequest = $.ajax( { 982 type: 'GET', 983 url: vueInstance.getTemplateUrl, 984 dataType: 'json', 985 data: { 986 'id': vueInstance.itemDataObject.megaTemplateId, 987 'dev': window.jetMenuPublicSettings.devMode, 988 'signature': signature 989 }, 990 beforeSend: function( jqXHR, ajaxSettings ) { 991 992 if ( null !== vueInstance.ajaxRequest ) { 993 vueInstance.ajaxRequest.abort(); 994 } 995 996 vueInstance.templateLoadStatus = true; 997 998 jqXHR.setRequestHeader( 'X-WP-Nonce', window.jetMenuPublicSettings.restNonce ); 999 }, 1000 success: function( responce, textStatus, jqXHR ) { 1001 let templateContent = responce['content'], 1002 contentElements = responce['contentElements']; 1003 1004 vueInstance.templateLoadStatus = false; 1005 vueInstance.itemDataObject.megaContent = templateContent; 1006 vueInstance.itemDataObject.megaContentLoaded = true; 1007 1008 jetMenu.eventBus.$emit( 'showTemplateContent', { 1009 menuUniqId: vueInstance.$root.menuOptions.menuUniqId, 1010 id: vueInstance.itemDataObject.id, 1011 name: vueInstance.itemDataObject.name, 1012 megaContent: vueInstance.itemDataObject.megaContent, 1013 megaContentType: vueInstance.itemDataObject.megaContentType, 1014 } ); 1015 } 1016 } ); 1017 } 1018 } 1019 1020 }); 1021 1022 Vue.component( 'mobile-menu-list', { 1023 template: '#mobile-menu-list-template', 1024 props: { 1025 depth: Number, 1026 childrenObject: Object 1027 } 1028 } ); 1029 1030 Vue.component( 'mobile-menu', { 1031 template: '#mobile-menu-template', 1032 1033 data: function() { 1034 return ( { 1035 menuOpen: false, 1036 children: false, 1037 itemsRawData: {}, 1038 trail:[], 1039 breadcrumbsData: [], 1040 animation: 'items-next-animation', 1041 ajaxRequest: null, 1042 templateVisible: false, 1043 instanceLoadStatus: false, 1044 itemTemplateContent: false, 1045 headerTemplate: this.$root.menuOptions['headerTemplate'] || 0, 1046 headerContent: false, 1047 beforeTemplate: this.$root.menuOptions['beforeTemplate'] || 0, 1048 beforeContent: false, 1049 afterTemplate: this.$root.menuOptions['afterTemplate'] || 0, 1050 afterContent: false, 1051 ajaxPromises: [], 1052 } ) 1053 }, 1054 1055 mounted: function() { 1056 const vueInstance = this; 1057 1058 if ( this.menuOpen ) { 1059 jetMenu.$body.addClass( 'jet-mobile-menu-visible' ); 1060 1061 if ( 'slide-out' === this.$root.menuOptions.menuLayout ) { 1062 jetMenu.$body.addClass( 'jet-menu-body-blocker' ); 1063 } 1064 } 1065 1066 let menuInstanceRenderData = false, 1067 renderDataElement = document.getElementById( 'jetMenuMobileWidgetRenderData' + this.$root.menuOptions.menuUniqId ); 1068 1069 if ( renderDataElement ) { 1070 eval( renderDataElement.innerHTML ); 1071 menuInstanceRenderData = window[ 'jetMenuMobileWidgetRenderData' + this.$root.menuOptions.menuUniqId ] || false; 1072 } 1073 1074 if ( menuInstanceRenderData ) { 1075 this.itemsRawData = menuInstanceRenderData['items']; 1076 1077 const headerTemplateData = menuInstanceRenderData.headerTemplateData || false, 1078 beforeTemplateData = menuInstanceRenderData.beforeTemplateData || false, 1079 afterTemplateData = menuInstanceRenderData.afterTemplateData || false; 1080 1081 if ( headerTemplateData ) { 1082 this.headerContent = headerTemplateData.content; 1083 } 1084 1085 if ( beforeTemplateData ) { 1086 this.beforeContent = beforeTemplateData.content; 1087 } 1088 1089 if ( afterTemplateData ) { 1090 this.afterContent = afterTemplateData.content; 1091 } 1092 } else { 1093 this.ajaxPromises.push( 1094 new Promise( function( resolve, reject ) { 1095 1096 $.ajax( { 1097 type: 'GET', 1098 url: window.jetMenuPublicSettings.menuItemsApiUrl, 1099 dataType: 'json', 1100 data: { 1101 'menu_id': vueInstance.menuId, 1102 'dev': window.jetMenuPublicSettings.devMode, 1103 'lang': window.jetMenuPublicSettings.wpmlLanguageCode || false 1104 }, 1105 beforeSend: function( jqXHR, ajaxSettings ) { 1106 jqXHR.setRequestHeader( 'X-WP-Nonce', window.jetMenuPublicSettings.restNonce ); 1107 }, 1108 success: function( responce, textStatus, jqXHR ) { 1109 let responceData = responce.data.items; 1110 1111 vueInstance.itemsRawData = responceData; 1112 1113 resolve(); 1114 } 1115 } ); 1116 } ) 1117 ); 1118 1119 if ( 0 !== +this.headerTemplate ) { 1120 this.ajaxPromises.push( 1121 new Promise( function( resolve, reject ) { 1122 $.ajax( { 1123 type: 'GET', 1124 url: window.jetMenuPublicSettings.getElementorTemplateApiUrl, 1125 dataType: 'json', 1126 data: { 1127 'id': vueInstance.headerTemplate, 1128 'dev': window.jetMenuPublicSettings.devMode, 1129 'nocache': new Date().getTime(), 1130 }, 1131 beforeSend: function( jqXHR, ajaxSettings ) { 1132 jqXHR.setRequestHeader( 'X-WP-Nonce', window.jetMenuPublicSettings.restNonce ); 1133 }, 1134 success: function( responce, textStatus, jqXHR ) { 1135 let templateContent = responce['content'], 1136 templateScripts = responce['scripts'], 1137 templateStyles = responce['styles']; 1138 1139 console.log(responce) 1140 1141 for ( let scriptHandler in templateScripts ) { 1142 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 1143 } 1144 1145 for ( let styleHandler in templateStyles ) { 1146 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 1147 } 1148 1149 vueInstance.headerContent = templateContent; 1150 1151 resolve(); 1152 } 1153 } ); 1154 } ) 1155 ); 1156 } 1157 1158 if ( 0 !== +this.beforeTemplate ) { 1159 this.ajaxPromises.push( 1160 new Promise( function( resolve, reject ) { 1161 $.ajax( { 1162 type: 'GET', 1163 url: window.jetMenuPublicSettings.getElementorTemplateApiUrl, 1164 dataType: 'json', 1165 data: { 1166 'id': vueInstance.beforeTemplate, 1167 'dev': window.jetMenuPublicSettings.devMode, 1168 'nocache': new Date().getTime(), 1169 }, 1170 beforeSend: function( jqXHR, ajaxSettings ) { 1171 jqXHR.setRequestHeader( 'X-WP-Nonce', window.jetMenuPublicSettings.restNonce ); 1172 }, 1173 success: function( responce, textStatus, jqXHR ) { 1174 let templateContent = responce['content'], 1175 templateScripts = responce['scripts'], 1176 templateStyles = responce['styles']; 1177 1178 for ( let scriptHandler in templateScripts ) { 1179 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 1180 } 1181 1182 for ( let styleHandler in templateStyles ) { 1183 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 1184 } 1185 1186 vueInstance.beforeContent = templateContent; 1187 1188 resolve(); 1189 } 1190 } ); 1191 } ) 1192 ); 1193 } 1194 1195 if ( 0 !== +this.afterTemplate ) { 1196 this.ajaxPromises.push( 1197 new Promise( function( resolve, reject ) { 1198 $.ajax( { 1199 type: 'GET', 1200 url: window.jetMenuPublicSettings.getElementorTemplateApiUrl, 1201 dataType: 'json', 1202 data: { 1203 'id': vueInstance.afterTemplate, 1204 'dev': window.jetMenuPublicSettings.devMode, 1205 'nocache': new Date().getTime(), 1206 }, 1207 beforeSend: function( jqXHR, ajaxSettings ) { 1208 jqXHR.setRequestHeader( 'X-WP-Nonce', window.jetMenuPublicSettings.restNonce ); 1209 }, 1210 success: function( responce, textStatus, jqXHR ) { 1211 let templateContent = responce['content'], 1212 templateScripts = responce['scripts'], 1213 templateStyles = responce['styles']; 1214 1215 for ( let scriptHandler in templateScripts ) { 1216 jetMenu.addedAssetsPromises.push( jetMenu.loadScriptAsync( scriptHandler, templateScripts[ scriptHandler ] ) ); 1217 } 1218 1219 for ( let styleHandler in templateStyles ) { 1220 jetMenu.addedAssetsPromises.push( jetMenu.loadStyle( styleHandler, templateStyles[ styleHandler ] ) ); 1221 } 1222 1223 vueInstance.afterContent = templateContent; 1224 resolve(); 1225 } 1226 } ); 1227 } ) 1228 ); 1229 } 1230 } 1231 1232 1233 1234 this.instanceLoadStatus = true; 1235 1236 Promise.all( this.ajaxPromises ).then( function() { 1237 vueInstance.instanceLoadStatus = false;
1238 //vueInstance.initTemplatesContent(); 1239 }, function( reason ) { 1240 console.log( 'Script Loaded Error' ); 1241 } ); 1242 1243 jetMenu.eventBus.$on( 'itemsSubSwitch', function ( payLoad ) { 1244 1245 if ( vueInstance.$root.menuOptions.menuUniqId !== payLoad.menuUniqId ) { 1246 return; 1247 } 1248 1249 vueInstance.trail.push( payLoad.children ); 1250 vueInstance.children = payLoad.children; 1251 vueInstance.animation = 'items-next-animation'; 1252 vueInstance.breadcrumbsData.push( payLoad.name ); 1253 } ); 1254 1255 jetMenu.eventBus.$on( 'showTemplateContent', function ( payLoad ) { 1256 1257 if ( vueInstance.$root.menuOptions.menuUniqId !== payLoad.menuUniqId ) { 1258 return; 1259 } 1260 1261 vueInstance.itemTemplateContent = payLoad.megaContent.content; 1262 vueInstance.templateVisible = true; 1263 vueInstance.breadcrumbsData.push( payLoad.name ); 1264 vueInstance.animation = 'items-next-animation'; 1265 1266 const templateData = { 1267 content: payLoad.megaContent.content !== undefined 1268 ? payLoad.megaContent.content 1269 : payLoad.megaContent, 1270 contentElements: payLoad.megaContent.contentElements, 1271 contentType: payLoad.megaContentType, 1272 } 1273 1274 vueInstance.showTemplateContent( templateData ); 1275 } ); 1276 1277 jetMenu.eventBus.$on( 'closeMenu', function( payLoad ) { 1278 1279 if ( vueInstance.$root.menuOptions.menuUniqId !== payLoad.menuUniqId ) { 1280 return; 1281 } 1282 1283 vueInstance.closeMenu(); 1284 } ); 1285 1286 }, 1287 1288 watch: { 1289 menuOpen: function( curr, prev ) { 1290 1291 if ( curr ) { 1292 jetMenu.$body.addClass( 'jet-mobile-menu-visible' ); 1293 1294 if ( 'slide-out' === this.$root.menuOptions.menuLayout ) { 1295 jetMenu.$body.addClass( 'jet-menu-body-blocker' ); 1296 } 1297 1298 this.initTemplatesContent(); 1299 } 1300 1301 if ( ! curr ) { 1302 jetMenu.$body.removeClass( 'jet-mobile-menu-visible' ); 1303 1304 if ( 'slide-out' === this.$root.menuOptions.menuLayout ) { 1305 jetMenu.$body.removeClass( 'jet-menu-body-blocker' ); 1306 } 1307 1308 this.clearStates(); 1309 } 1310 } 1311 }, 1312 1313 computed: { 1314 instanceClass: function() { 1315 1316 let classes = [ 1317 'jet-mobile-menu__instance', 1318 'jet-mobile-menu__instance--' + this.$root.menuOptions.menuLayout + '-layout', 1319 this.$root.menuOptions.menuPosition + '-container-position', 1320 ( this.$root.menuOptions.togglePosition || 'default' ) + '-toggle-position', 1321 this.$root.menuOptions.fillSvgIcon ? 'fill-svg-icon' : '', 1322 ]; 1323 1324 return classes; 1325 }, 1326 1327 menuContainerVisible: function() { 1328 return this.menuOpen && !this.instanceLoadStatus; 1329 }, 1330 1331 menuId: function() { 1332 1333 if ( this.$root.menuOptions.mobileMenuId && window.jetMenuPublicSettings.isMobile === 'true' ) { 1334 return this.$root.menuOptions.mobileMenuId; 1335 } 1336 1337 return this.$root.menuOptions.menuId; 1338 }, 1339 1340 coverVisible: function() { 1341 1342 let avaliableForLayout = [ 1343 'slide-out' 1344 ]; 1345 1346 return avaliableForLayout.includes( this.$root.menuOptions.menuLayout ); 1347 }, 1348 1349 itemsList: function() { 1350 1351 if ( ! this.children ) { 1352 return this.itemsRawData; 1353 } 1354 1355 return this.children; 1356 }, 1357 1358 isClose: function() { 1359 let avaliableForLayout = [ 1360 'slide-out' 1361 ]; 1362 1363 return avaliableForLayout.includes( this.$root.menuOptions.menuLayout ); 1364 }, 1365 1366 isBack: function() { 1367 return this.children || this.templateVisible ? true : false; 1368 }, 1369 1370 isBreadcrumbs: function() { 1371 return this.$root.menuOptions.useBreadcrumb && 0 !== this.breadcrumbsData.length ? true : false; 1372 }, 1373 1374 breadcrumbsPathData: function() { 1375 1376 if ( 'minimal' === this.$root.$root.menuOptions.breadcrumbPath && 1 < this.breadcrumbsData.length ) { 1377 return this.breadcrumbsData.filter( ( item, index, breadcrumbsData ) => { 1378 return index === breadcrumbsData.length - 1; 1379 } ); 1380 } 1381 1382 return this.breadcrumbsData; 1383 }, 1384 1385 depth: function() { 1386 return this.trail.length; 1387 }, 1388 1389 containerPosition: function() { 1390 return this.$root.menuOptions.menuPosition; 1391 }, 1392 1393 showAnimation: function() { 1394 1395 let animation = false;
1396 1397 switch( this.$root.menuOptions.menuLayout ) { 1398 1399 case 'slide-out': 1400 animation = 'right' === this.containerPosition ? 'menu-container-left-animation' : 'menu-container-right-animation'; 1401 break; 1402 1403 case 'dropdown': 1404 animation = 'menu-container-dropdown-animation'; 1405 break; 1406 1407 case 'push': 1408 animation = 'menu-container-expand-animation'; 1409 break; 1410 } 1411 1412 return animation; 1413 }, 1414 1415 toggleClosedIcon: function() { 1416 return this.$root.refsHtml.toggleClosedIcon || ''; 1417 }, 1418 1419 toggleOpenedIcon: function() { 1420 return this.$root.refsHtml.toggleOpenedIcon || ''; 1421 }, 1422 1423 toggleText: function() { 1424 return '' !== this.$root.menuOptions.toggleText ? this.$root.menuOptions.toggleText : false; 1425 }, 1426 1427 closeIcon: function() { 1428 return this.$root.refsHtml.closeIcon || ''; 1429 }, 1430 1431 backIcon: function() { 1432 let backIcon = this.$root.refsHtml.backIcon || '', 1433 backText = '' !== this.$root.menuOptions.backText ? '<span>' + this.$root.menuOptions.backText + '</span>' : '', 1434 backHtml = backIcon + backText; 1435 1436 return backHtml; 1437 }, 1438 1439 backText: function() { 1440 return '' !== this.$root.menuOptions.backText ? this.$root.menuOptions.backText : false; 1441 }, 1442 1443 breadcrumbIcon: function() { 1444 return this.$root.refsHtml.breadcrumbIcon || ''; 1445 }, 1446 1447 loaderColor: function() { 1448 return this.$root.menuOptions.loaderColor || '#3a3a3a'; 1449 }, 1450 1451 toggleLoaderVisible: function() { 1452 return this.$root.menuOptions.toggleLoader && this.instanceLoadStatus && this.menuOpen ? true : false; 1453 }, 1454 1455 headerTemplateVisible: function() { 1456 return this.headerContent ? true : false; 1457 }, 1458 1459 beforeTemplateVisible: function() { 1460 return this.beforeContent ? true : false; 1461 }, 1462 1463 afterTemplateVisible: function() { 1464 return this.afterContent ? true : false; 1465 } 1466 1467 }, 1468 1469 methods: { 1470 menuToggle: function() { 1471 this.menuOpen = ! this.menuOpen; 1472 }, 1473 1474 closeMenu: function() { 1475 this.menuOpen = false; 1476 }, 1477 1478 clearStates: function() { 1479 this.trail = []; 1480 this.children = false; 1481 this.breadcrumbsData = []; 1482 this.templateVisible = false; 1483 }, 1484 1485 goBack: function() { 1486 1487 this.animation = 'items-prev-animation'; 1488 1489 if ( ! this.templateVisible ) { 1490 this.$delete( this.trail, this.trail.length - 1 ); 1491 this.children = this.trail.slice(-1)[0] || false; 1492 } else { 1493 this.templateVisible = false; 1494 } 1495 1496 this.$delete(this.breadcrumbsData, this.breadcrumbsData.length - 1); 1497 }, 1498 1499 escapeKeyHandler: function() { 1500 1501 if ( this.isBack ) { 1502 this.goBack(); 1503 } else { 1504 this.closeMenu(); 1505 } 1506 }, 1507 1508 showTemplateContent: function( templateData = {} ) { 1509 let vueInstance = this; 1510 1511 this.$nextTick( function() { 1512 let $templateContainer = $( vueInstance.$refs['template-content'] ).find( '.jet-mobile-menu__template-content' ); 1513 1514 jetMenu.megaContentRender( $templateContainer, templateData ); 1515 } ); 1516 }, 1517 1518 initTemplatesContent: function() { 1519 let vueInstance = this; 1520 1521 this.$nextTick( function() { 1522 1523 if ( vueInstance.headerContent ) { 1524 let $headerContainer = $( vueInstance.$refs['header-template-content'] ); 1525 1526 jetMenu.megaContentRender( $headerContainer, { contentType: 'elementor' } ); 1527 } 1528 1529 if ( vueInstance.beforeContent ) { 1530 let $beforeContainer = $( vueInstance.$refs['before-template-content'] ); 1531 1532 jetMenu.megaContentRender( $beforeContainer, { contentType: 'elementor' } ); 1533 } 1534 1535 if ( vueInstance.afterContent ) { 1536 let $afterContainer = $( vueInstance.$refs['after-template-content'] ); 1537 1538 jetMenu.megaContentRender( $afterContainer, { contentType: 'elementor' } ); 1539 } 1540 } ); 1541 }, 1542 1543 breadcrumbHandle: function( index ) { 1544 1545 if ( index === this.breadcrumbsData.length ) { 1546 return; 1547 } 1548 1549 if ( 'minimal' === this.$root.menuOptions.breadcrumbPath ) { 1550 this.goBack(); 1551 1552 return; 1553 } 1554 1555 this.animation = 'items-prev-animation'; 1556 this.trail = this.trail.slice( 0, index ); 1557 this.children = this.trail.slice( -1 )[0] || false; 1558 this.templateVisible = false;
1559 this.breadcrumbsData = this.breadcrumbsData.slice( 0, index ); 1560 } 1561 1562 } 1563 }); 1564 }, 1565 1566 loadScriptAsync: function( script, uri ) { 1567 1568 if ( jetMenu.addedScripts.hasOwnProperty( script ) ) { 1569 return script; 1570 } 1571 1572 jetMenu.addedScripts[ script ] = uri; 1573 1574 return new Promise( function( resolve, reject ) { 1575 var tag = document.createElement( 'script' ); 1576 1577 tag.src = uri; 1578 tag.async = true; 1579 tag.onload = function() { 1580 resolve( script ); 1581 }; 1582 1583 document.head.appendChild( tag ); 1584 } ); 1585 }, 1586 1587 loadStyle: function( style, uri ) { 1588 1589 if ( jetMenu.addedStyles.hasOwnProperty( style ) && jetMenu.addedStyles[ style ] === uri) { 1590 return style; 1591 } 1592 1593 jetMenu.addedStyles[ style ] = uri; 1594 1595 return new Promise( function( resolve, reject ) { 1596 var tag = document.createElement( 'link' ); 1597 1598 tag.id = style; 1599 tag.rel = 'stylesheet'; 1600 tag.href = uri; 1601 tag.type = 'text/css'; 1602 tag.media = 'all'; 1603 tag.onload = function() { 1604 resolve( style ); 1605 }; 1606 1607 document.head.appendChild( tag ); 1608 }); 1609 }, 1610 1611 megaContentRender: function( $templateContainer, templateData = {} ) { 1612 1613 if ( templateData.content ) { 1614 $templateContainer.html( templateData.content ); 1615 } 1616 1617 const data = { 1618 $container: $templateContainer, 1619 ...templateData 1620 } 1621 1622 Promise.all( jetMenu.addedAssetsPromises ).then( function( value ) { 1623 // Before ajax frontend init 1624 $( window ).trigger( 'jet-menu/ajax/frontend-init/before', data ); 1625 1626 // Frontend init 1627 $( window ).trigger( 'jet-menu/ajax/frontend-init', data ); 1628 1629 // after ajax frontend init 1630 $( window ).trigger( 'jet-menu/ajax/frontend-init/after', data ); 1631 }, function( reason ) { 1632 console.log( 'Script Loaded Error' ); 1633 }); 1634 }, 1635 1636 maybeElementorFrontendInit: function( $templateContainer ) { 1637 1638 $templateContainer.find( 'div[data-element_type]' ).each( function() { 1639 var $this = $( this ), 1640 elementType = $this.data( 'element_type' ); 1641 1642 if ( ! elementType ) { 1643 return; 1644 } 1645 1646 try { 1647 if ( 'widget' === elementType ) { 1648 elementType = $this.data( 'widget_type' ); 1649 1650 if ( window.elementorFrontend && window.elementorFrontend.hooks ) { 1651 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 1652 } 1653 } 1654 1655 if ( window.elementorFrontend && window.elementorFrontend.hooks ) { 1656 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 1657 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 1658 } 1659 1660 } catch ( err ) { 1661 console.log(err); 1662 $this.remove(); 1663 1664 return false; 1665 } 1666 } ); 1667 }, 1668 1669 maybeDefaultFrontendInit: function ( payload ) { 1670 const contentElements = payload.contentElements || [], 1671 $container = payload.$container; 1672 1673 $container.find( '[data-is-block*="/"]' ).each( ( index, el ) => { 1674 window.JetPlugins.hooks.doAction( window.JetPlugins.hookNameFromBlock( el.dataset.isBlock ), jQuery( el ) ); 1675 } ); 1676 }, 1677 1678 getUniqId: function() { 1679 return Math.random().toString( 36 ).substr( 2, 9 ); 1680 }, 1681 1682 }; 1683 1684 jetMenu.init(); 1685 1686} ( jQuery ) ); 1687
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.