1( function( $ ) { 2 'use strict'; 3 4 var KurtosysMenu = function( element, options ) { 5 6 this.defaultSettings = { 7 enabled: false, 8 threshold: 767, // Minimal menu width, when this plugin activates 9 mouseLeaveDelay: 500, 10 openSubType: 'click', // hover, click 11 megaWidthType: 'container', 12 megaWidthSelector: '', 13 mainMenuSelector: '.kurtosys-menu', 14 menuInnerSelector: '.kurtosys-menu-inner', 15 menuItemSelector: '.kurtosys-menu-item', 16 moreMenuContent: '···', 17 templates: { 18 mobileMenuToogleButton: '<button class="kurtosys-mobile-menu-toggle-button" aria-label="Menu" aria-expanded="false" aria-controls="kurtosys-menu-"><i class="kurtosys-menu-toggle__icon"></i></button>', 19 } 20 } 21 22 this.settings = $.extend( this.defaultSettings, options ); 23 24 this.$window = $( window ); 25 26 this.$document = $( document ); 27 28 this.$element = $( element ); 29 30 this.$instance = $( this.settings.mainMenuSelector, this.$element ).addClass( 'kurtosys-responsive-menu' ); 31 32 this.$menuItems = $( '>' + this.settings.menuItemSelector, this.$instance ).addClass( 'kurtosys-responsive-menu-item' ); 33 34 this.$moreItemsInstance = null; 35 36 this.hiddenItemsArray = []; 37 38 this.$mobileStateCover = null; 39 40 this.createMenuInstance(); 41 42 this.$instance.trigger( 'kurtosysMenuCreated' ); 43 } 44 45 KurtosysMenu.prototype = { 46 constructor: KurtosysMenu, 47 48 createMenuInstance: function() { 49 var self = this, 50 mainMenuWidth, 51 totalVisibleItemsWidth = 0; 52 53 this.subMenuRebuild(); 54 this.subMegaMenuRebuild(); 55 56 // Add mobile menu cover 57 $( 'body' ).append( '<div class="kurtosys-mobile-menu-cover"></div>' ); 58 this.$mobileStateCover = $( '.kurtosys-mobile-menu-cover' ); 59 60 // Add available items list 61 if ( ! tools.isEmpty( this.settings.moreMenuContent ) && self.settings.enabled ) { 62 self.$instance.append( '<li class="kurtosys-menu-item kurtosys-menu-item-has-children kurtosys-simple-menu-item kurtosys-responsive-menu-available-items" hidden><a href="#" class="top-level-link"><div class="kurtosys-menu-item-wrapper">' + this.settings.moreMenuContent + '</div></a><ul class="kurtosys-sub-menu"></ul></li>' ); 63 self.$moreItemsInstance = $( '> .kurtosys-responsive-menu-available-items', this.$instance ); 64 self.$moreItemsInstance.attr( { 'hidden': 'hidden' } ); 65 } 66 67 // Add mobile menu toogle button 68 if ( ! tools.isEmpty( this.settings.templates.mobileMenuToogleButton ) ) { 69 this.$element.prepend( this.settings.templates.mobileMenuToogleButton ); 70 this.$mobileToogleButton = $( '.kurtosys-mobile-menu-toggle-button', this.$element ); 71 // Set toogle button aria-controls with id of inner menu 72 const menuInnerId = $(this.settings.menuInnerSelector, this.$element).attr('id'); 73 this.$mobileToogleButton.attr('aria-controls', menuInnerId); 74 } 75 76 if ( this.isThreshold() ) { 77 this.$element.addClass( 'kurtosys-mobile-menu' ); 78 $( 'body' ).addClass( 'kurtosys-mobile-menu-active' ); 79 } else { 80 $( 'body' ).addClass( 'kurtosys-desktop-menu-active' ); 81 this.rebuildItems(); 82 this.$instance.trigger( 'rebuildItems' ); // subMenu position rebuild 83 } 84 85 this.subMenuHandler(); 86 87 this.mobileViewHandler(); 88 89 this.watch(); 90 }, 91 92 /** 93 * SubMenu items Handler. 94 * 95 * @return {void} 96 */ 97 subMenuHandler: function() { 98 var self = this, 99 transitionend = 'transitionend oTransitionEnd webkitTransitionEnd', 100 prevClickedItem = null, 101 menuItem, 102 menuItemParents, 103 timer; 104 105 if ( self.mobileAndTabletcheck() ) { 106 this.$instance.on( 'touchstart', '.kurtosys-menu-item > a', touchStartItem ); 107 this.$instance.on( 'touchend', '.kurtosys-menu-item > a', touchEndItem ); 108 } else { 109 110 switch ( this.settings.openSubType ) { 111 case 'hover': 112 this.$instance.on( 'mouseenter focus', '.kurtosys-menu-item > a', mouseEnterHandler ); 113 this.$instance.on( 'mouseleave blur', '.kurtosys-menu-item > a', mouseLeaveHandler ); 114 115 break; 116 case 'click': 117 this.$instance.on( 'click', '.kurtosys-menu-item > a', clickHandler ); 118 break; 119 } 120 121 this.$instance.on( 'mouseenter', '.kurtosys-sub-menu, .kurtosys-sub-mega-menu', mou
121seEnterSubMenuHandler ); 122 this.$instance.on( 'mouseenter', mouseEnterInstanceHandler ); 123 this.$instance.on( 'mouseleave', mouseLeaveInstanceHandler ); 124 } 125 126 function touchStartItem( event ) { 127 var $currentTarget = $( event.currentTarget ), 128 $this = $currentTarget.closest('.kurtosys-menu-item'); 129 130 $this.data( 'offset', $this.offset().top ); 131 } 132 133 function touchEndItem( event ) { 134 var $this, 135 $siblingsItems, 136 $link, 137 $currentTarget, 138 subMenu, 139 offset; 140 141 event.preventDefault(); 142 event.stopPropagation(); 143 144 $currentTarget = $( event.currentTarget ); 145 $this = $currentTarget.closest('.kurtosys-menu-item'); 146 $siblingsItems = $this.siblings( '.kurtosys-menu-item.kurtosys-menu-item-has-children' ); 147 $link = $( '> a', $this ); 148 subMenu = $( '.kurtosys-sub-menu:first, .kurtosys-sub-mega-menu', $this ); 149 offset = $this.data( 'offset' ); 150 151 if ( offset !== $this.offset().top ) { 152 return false; 153 } 154 155 if ( $siblingsItems[0] ) { 156 $siblingsItems.removeClass( 'kurtosys-menu-hover' ); 157 $( 'kurtosys-menu-item-has-children', $siblingsItems ).removeClass( 'kurtosys-menu-hover' ); 158 } 159 160 if ( ! $( '.kurtosys-sub-menu, .kurtosys-sub-mega-menu', $this )[0] || $this.hasClass( 'kurtosys-menu-hover' ) ) { 161 window.location = $link.attr( 'href' ); 162 163 $( 'body' ).removeClass( 'kurtosys-mobile-menu-visible' ); 164 self.$element.removeClass( 'kurtosys-mobile-menu-active-state' ); 165 166 return false; 167 } 168 169 if ( subMenu[0] ) { 170 $this.addClass( 'kurtosys-menu-hover' ); 171 self.handleMobileSubmenu(subMenu[0]); 172 } 173 } 174 175 function clickHandler( event ) { 176 var $this, 177 $siblingsItems, 178 $link, 179 $currentTarget, 180 subMenu; 181 182 event.preventDefault(); 183 event.stopPropagation(); 184 185 $currentTarget = $( event.currentTarget ); 186 $this = $currentTarget.closest('.kurtosys-menu-item'); 187 $siblingsItems = $this.siblings( '.kurtosys-menu-item.kurtosys-menu-item-has-children' ); 188 $link = $( '> a', $this ); 189 subMenu = $( '.kurtosys-sub-menu:first, .kurtosys-sub-mega-menu', $this ); 190 191 if ( $siblingsItems[0] ) { 192 $siblingsItems.removeClass( 'kurtosys-menu-hover' ); 193 $( 'kurtosys-menu-item-has-children', $siblingsItems ).removeClass( 'kurtosys-menu-hover' ); 194 const siblingLinkElements = $( '> .top-level-link', $siblingsItems ); 195 siblingLinkElements.attr( 'aria-expanded', 'false' ); 196 } 197 198 if ( ! $( '.kurtosys-sub-menu, .kurtosys-sub-mega-menu', $this )[0] || $this.hasClass('kurtosys-menu-hover') ) { 199 window.location = $link.attr( 'href' ); 200 201 $( 'body' ).removeClass( 'kurtosys-mobile-menu-visible' ); 202 self.$element.removeClass( 'kurtosys-mobile-menu-active-state' ); 203 204 return false; 205 } 206 207 if ( subMenu[0] ) { 208 $link.attr( 'aria-expanded', 'true' ); 209 $this.addClass( 'kurtosys-menu-hover' ); 210 self.handleMobileSubmenu(subMenu[0]); 211 } 212 } 213 214 function mouseEnterHandler( event ) { 215 var subMenu; 216 217 menuItem = $( event.target ).parents( '.kurtosys-menu-item' ); 218 subMenu = menuItem.children( '.kurtosys-sub-menu, .kurtosys-sub-mega-menu' ).first(); 219 220 $( '.kurtosys-menu-hover', this.$instance ).removeClass( 'kurtosys-menu-hover' ); 221 222 if ( subMenu[0] ) { 223 const linkElement = $(event.target); 224 if (linkElement.hasClass( 'top-level-link' )) { 225 linkElement.attr( 'aria-expanded', 'true' ); 226 } 227 menuItem.addClass( 'kurtosys-menu-hover' ); 228 self.handleMobileSubmenu(subMenu[0]); 229 } 230 } 231 232 function mouseLeaveHandler( event ) { 233 // Item Mouse Leave Event 234 const menuItem = $(event.target).parents( '.kurtosys-menu-item-has-children' ); 235 const linkElement = menuItem.find(' > .top-level-link' ); 236 237 timer = setTimeout( function() { 238 if (!menuItem.hasClass( 'kurtosys-menu-hover' )) { 239 linkElement.attr( 'aria-expanded', 'false' ); 240 } 241 }, self.settings.mouseLeaveDelay + 1 ); 242 } 243 244 function mouseEnterSubMenuHandler( event ) { 245 clearTimeout( timer ); 246 } 247 248 function mouseEnterInstanceHandler( event ) { 249 clearTimeout( timer ); 250 } 251 252 function mouseLeaveInstanceHandler( event ) { 253 const linkElement = $( '.kurtosys-menu-hover > .top-level-link', this.$instance ); 254 timer = setTimeout( function() { 255 $( '.kurtosys-menu-hover', this.$instance ).removeClass( 'kurtosys-menu-hover' ); 256 linkElement.attr( 'aria-expanded', 'false' ); 257 }, self.settings.mouseLeaveDelay ); 258 } 259 260 var windowWidth = $( window ).width(); 261 262 self.$window.on( 'orientationchange resize', function( event ) { 263 if ( $( 'body' ).hasClass( 'kurtosys-mobile-menu-active' ) ) { 264 return; 265 } 266
267 // Do not trigger a change if the viewport hasn't actually changed. Scrolling on iOS will trigger a resize. 268 if ( $( window ).width() === windowWidth ) { 269 return; 270 } 271 272 windowWidth = $( window ).width(); 273 274 self.$instance.find( '.kurtosys-menu-item' ).removeClass( 'kurtosys-menu-hover' ); 275 } ); 276 277 self.$document.on( 'touchend', function( event ) { 278 if ( $( 'body' ).hasClass( 'kurtosys-mobile-menu-active' ) ) { 279 return; 280 } 281 282 if ( $( event.target ).closest( '.kurtosys-menu-item' ).length ) { 283 return; 284 } 285 286 self.$instance.find( '.kurtosys-menu-item' ).removeClass( 'kurtosys-menu-hover' ); 287 } ); 288 289 }, 290 291 /** 292 * Mobile View Handler. 293 * 294 * @return {void} 295 */ 296 mobileViewHandler: function() { 297 var self = this, 298 toogleStartEvent = 'mousedown', 299 toogleEndEvent = 'click'; 300 301 if ( 'ontouchend' in window || 'ontouchstart' in window ) { 302 toogleStartEvent = 'touchstart'; 303 toogleEndEvent = 'touchend'; 304 } 305 306 this.$mobileToogleButton.on( toogleEndEvent, function( event ) { 307 $( 'body' ).toggleClass( 'kurtosys-mobile-menu-visible' ); 308 self.$element.toggleClass( 'kurtosys-mobile-menu-active-state' ); 309 self.$mobileToogleButton.attr( 'aria-expanded', (index, attr) => { return attr === 'true' ? 'false' : 'true'} ); 310 } ); 311 312 this.$document.on( toogleEndEvent, function( event ) { 313 if ( $( event.target ).closest( self.$element ).length ) { 314 return; 315 } 316 317 if ( ! self.$element.hasClass( 'kurtosys-mobile-menu' ) || ! self.$element.hasClass( 'kurtosys-mobile-menu-active-state' ) ) { 318 return; 319 } 320 321 $( 'body' ).removeClass( 'kurtosys-mobile-menu-visible' ); 322 self.$element.removeClass( 'kurtosys-mobile-menu-active-state' ); 323 self.$mobileToogleButton.attr( 'aria-expanded', (index, attr) => { return attr === 'true' ? 'false' : 'true'} ); 324 } ); 325 326 this.$document.on( 'keydown', function( event ) { 327 const menuOpen = $( 'body' ).hasClass( 'kurtosys-mobile-menu-visible' ); 328 if (event.keyCode === 27 && menuOpen) { 329 $( 'body' ).removeClass( 'kurtosys-mobile-menu-visible' ); 330 self.$element.removeClass( 'kurtosys-mobile-menu-active-state' ); 331 self.$mobileToogleButton.attr( 'aria-expanded', (index, attr) => { return attr === 'true' ? 'false' : 'true'} ); 332 } 333 }); 334 }, 335 336 /** 337 * Responsive menu watcher function. 338 * 339 * @param {number} Watcher debounce delay. 340 * @return {void} 341 */ 342 watch: function( delay ) { 343 var delay = delay || 10; 344 345 $( window ).on( 'resize.kurtosysResponsiveMenu orientationchange.kurtosysResponsiveMenu', this.debounce( delay, this.watcher.bind( this ) ) ); 346 this.$instance.trigger( 'containerResize' ); 347 }, 348 349 /** 350 * Responsive menu watcher callback. 351 * 352 * @param {Object} Resize or Orientationchange event. 353 * @return {void} 354 */ 355 watcher: function( event ) { 356 357 if ( this.isThreshold() ) { 358 this.$element.addClass( 'kurtosys-mobile-menu' ); 359 $( 'body' ).addClass( 'kurtosys-mobile-menu-active' ); 360 $( 'body' ).removeClass( 'kurtosys-desktop-menu-active' ); 361 this.$menuItems.removeAttr( 'hidden' ); 362 363 // More-items listing not empty checking 364 if ( 0 !== this.hiddenItemsArray.length ) { 365 $( '> .kurtosys-sub-menu', this.$moreItemsInstance ).empty(); 366 } 367 368 if ( this.settings.enabled ) { 369 this.$moreItemsInstance.attr( { 'hidden': 'hidden' } ); 370 } 371 372 } else { 373 this.$element.removeClass( 'kurtosys-mobile-menu' ); 374 $( 'body' ).removeClass( 'kurtosys-mobile-menu-active' ); 375 $( 'body' ).addClass( 'kurtosys-desktop-menu-active' ); 376 $( 'body' ).removeClass( 'kurtosys-mobile-menu-visible' ); 377 378 this.rebuildItems(); 379 this.$instance.trigger( 'rebuildItems' ); // subMenu position rebuild 380 this.$instance.trigger( 'containerResize' ); 381 this.$element.removeClass( 'kurtosys-mobile-menu-active-state' ); 382 this.$mobileToogleButton.attr( 'aria-expanded', 'false' ); 383 } 384 }, 385 386 /** 387 * Responsive Menu rebuilding function. 388 * 389 * @return {void} 390 */ 391 rebuildItems: function() { 392 393 if ( ! this.settings.enabled ) { 394 return false; 395 } 396 397 var self = this, 398 mainMenuWidth = this.$instance.width(), 399 correctedMenuWidth = this.$instance.width() - self.$moreItemsInstance.outerWidth( true ), 400 iterationVisibleItemsWidth = 0, 401 iterationHiddenItemsWidth = this.getVisibleItemsWidth(), 402 visibleItemsArray = [], 403 hiddenItemsArray = []; 404 405 self.$menuItems.each( function() { 406 var $this = $( this ); 407 408 iterationVisibleItemsWidth += $this.outerWidth( true ); 409 410 if ( iterationVisibleItemsWidth > correctedMenuWidth && ! tools.inArray( this, hiddenItemsArray ) ) { 411 hiddenItemsArray.push( this ); 412 } else { 413 visibleItemsArray.push( this ); 414 } 415 416 } ); 417 418 hiddenItemsArray.forEach( function( item ) { 419 var $item = $( item ); 420 421 $item.attr( { 'hidden': 'hidden' } ); 422 } ); 423 424 visibleItemsArray.forEach( function( item, index ) { 425 var $item = $( item ); 426 427 $item.removeAttr( 'hidden' ); 428 } ); 429 430 $( '> .kurtosys-sub-menu', self.$moreItemsInstance ).empty(); 431 432 hiddenItemsArray.forEach( function( item ) { 433 var $clone = $( item ).clone(); 434 435 // Remove sub-mega-menu content 436 $( '.kurtosys-sub-mega-menu', $clone ).remove(); 437 438 $clone.addClass( 'kurtosys-sub-menu-item' ); 439 440 $clone.removeAttr( 'hidden' ); 441 442 $( '> .top-level-link', $clone ).toggleClass( 'top-level-link sub-level-link' ); 443 444 $( '> .kurtosys-sub-menu', self.$moreItemsInstance ).append( $clone ); 445 } ); 446 447 if ( 0 == hiddenItemsArray.length ) { 448 self.$moreItemsInstance.attr( { 'hidden': 'hidden' } ); 449 self.$moreItemsInstance.addClass( 'kurtosys-empty' ); 450 } else { 451 self.$moreItemsInstance.removeAttr( 'hidden' ); 452 self.$moreItemsInstance.removeClass( 'kurtosys-empty' ); 453 } 454 455 self.hiddenItemsArray = hiddenItemsArray; 456 457 //this.$instance.trigger( 'rebuildItems' ); // when `Menu rollUp` is disabled `rebuildItems`(subMenu position rebuild) trigger does not work 458 }, 459 460 /** 461 * Sub Menu rebuilding function. 462 * 463 * @return {void} 464 */ 465 subMenuRebuild: function() { 466 var self = this, 467 initSubMenuPosition = false;
468 469 this.$instance.on( 'rebuildItems', function() { 470 var $subMenuList = $( '.kurtosys-sub-menu', self.$instance ), 471 maxWidth = self.$window.outerWidth( true ); 472 473 if ( ! $subMenuList[0] ) { 474 return; 475 } 476 477 if ( initSubMenuPosition ) { 478 $subMenuList.removeClass( 'right-side' ); 479 initSubMenuPosition = false; 480 } 481 482 $subMenuList.each( function() { 483 var $this = $( this ), 484 subMenuOffset = $this.offset().left, 485 subMenuPos = subMenuOffset + $this.outerWidth( true ); 486 487 if ( subMenuPos >= maxWidth ) { 488 $this.addClass( 'right-side' ); 489 $this.find( '.kurtosys-sub-menu' ).addClass( 'right-side' ); 490 491 initSubMenuPosition = true; 492 } else if ( subMenuOffset < 0 ) { 493 $this.removeClass( 'right-side' ); 494 $this.find( '.kurtosys-sub-menu' ).removeClass( 'right-side' ); 495 } 496 497 } ); 498 } ); 499 }, 500 501 /** 502 * Sub Mega Menu rebuilding function. 503 * 504 * @return {void} 505 */ 506 subMegaMenuRebuild: function() { 507 var self = this; 508 509 this.$instance.on( 'containerResize', function() { 510 var $megaMenuList = $( '.kurtosys-sub-mega-menu', self.$instance ), 511 maxWidth = $( 'body' ).outerWidth( true ); 512 513 switch( self.settings.megaWidthType ) { 514 case 'items': 515 var visibleItemsWidth = self.getVisibleItemsWidth(), 516 firstOffset = $( '> .kurtosys-menu-item:first', self.$instance ).position().left; 517 518 $megaMenuList.css( { 519 'width': visibleItemsWidth + 'px', 520 'left': firstOffset 521 } ); 522 523 break; 524 case 'selector': 525 var customSelector = $( self.settings.megaWidthSelector ), 526 instanceOffset = null, 527 customSelectorOffset = null; 528 529 if ( customSelector[0] ) { 530 instanceOffset = self.$instance.offset().left; 531 customSelectorOffset = customSelector.offset().left; 532 533 $megaMenuList.css( { 534 'width': customSelector.outerWidth(), 535 'left': (customSelectorOffset - instanceOffset ) + 'px' 536 } ); 537 } 538 539 break; 540 } 541 542 if ( $megaMenuList[0] ) { 543 $megaMenuList.css( { 544 'maxWidth': '' 545 } ); 546 547 $megaMenuList.each( function() { 548 var $this = $( this ), 549 megaMenuOffsetLeft = $this.offset().left, 550 megaMenuOffsetRight = megaMenuOffsetLeft + $this.outerWidth( true ); 551 552 if ( megaMenuOffsetRight >= maxWidth ) { 553 $this.css( { 554 'maxWidth': maxWidth - megaMenuOffsetLeft 555 } ); 556 } 557 } ); 558 } 559 } ); 560 }, 561 562 /** 563 * Get visible items total width 564 * 565 * @return {int} 566 */ 567 getVisibleItemsWidth: function() { 568 var totalVisibleItemsWidth = 0; 569 570 this.$menuItems.each( function() { 571 var $this = $( this ); 572 573 if ( ! $this.hasAttr( 'hidden' ) ) { 574 totalVisibleItemsWidth += $this.outerWidth( true ); 575 } 576 577 } ); 578 579 return totalVisibleItemsWidth; 580 }, 581 582 /** 583 * Get mobile status. 584 * 585 * @return {boolean} Mobile Status 586 */ 587 isThreshold: function() { 588 return ( this.$window.width() < this.settings.threshold ) ? true : false; 589 }, 590 591 /** 592 * Mobile and tablet check funcion. 593 * 594 * @return {boolean} Mobile Status 595 */ 596 mobileAndTabletcheck: function() { 597 var check = false; 598 599 (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 )|
599sy(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); 600 601 return check; 602 }, 603 604 /** 605 * Debounce the function call 606 * 607 * @param {number} threshold The delay. 608 * @param {Function} callback The function. 609 */ 610 debounce: function ( threshold, callback ) { 611 var timeout; 612 613 return function debounced( $event ) { 614 function delayed() { 615 callback.call( this, $event ); 616 timeout = null; 617 } 618 619 if ( timeout ) { 620 clearTimeout( timeout ); 621 } 622 623 timeout = setTimeout( delayed, threshold ); 624 }; 625 }, 626 627 /** 628 * WP-10261: The embedded Elementor Section's dynamic size/positioning logic breaks our 629 * submenu layouts when in mobile view, so manually repair them by unsetting the properties 630 * that cause the breakage. 631 */ 632 handleMobileSubmenu: function (subMenu) { 633 const menuContent = $(subMenu).find('.elementor-section-wrap>section').first(); 634 if (this.isThreshold()) { 635 $(menuContent).css('left', ''); 636 $(menuContent).css('width', ''); 637 } 638 } 639 } 640 641 /* 642 * Js tools 643 */ 644 var tools = { 645 isEmpty: function( value ) { 646 return ( ( false === value ) || ( '' === value ) || ( null === value ) || ( undefined === value )); 647 }, 648 649 isEmptyObject: function( value ) { 650 return ( true === this.isEmpty( value ) ) || ( 0 === value.length ); 651 }, 652 653 isString: function(value) { 654 return ( ( 'string' === typeof value ) || ( value instanceof String ) ); 655 }, 656 657 isArray: function( value ) { 658 return $.isArray( value ); 659 }, 660 661 inArray: function( value, array ) { 662 return ( $.inArray( value, array ) !== -1); 663 } 664 }; 665 666 /* 667 * Jq tools 668 */ 669 $.fn.hasAttr = function( name ) { 670 return this.attr( name ) !== undefined; 671 }; 672 673 // jQuery plugin 674 $.fn.KurtosysMenu = function( options ) { 675 return this.each( function() { 676 var $this = $( this ), 677 pluginOptions = ( 'object' === typeof options ) ? options : {}; 678 679 if ( ! $this.data( 'KurtosysMenu' ) ) { 680 681 // create plugin instance (only if not exists) and expose the entire instance API 682 $this.data( 'KurtosysMenu', new KurtosysMenu( this, pluginOptions ) ); 683 } 684 } ); 685 }; 686 687}( jQuery ) );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.