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