1/** 2* @package Gridbox template 3* @author Balbooa http://www.balbooa.com/ 4* @copyright Copyright @ Balbooa 5* @license http://www.gnu.org/licenses/gpl.html GNU/GPL 6*/ 7 8var recaptchaCommentsOnload = function() { 9 let str = '.ba-item-comments-box > .ba-comments-box-wrapper > .ba-comment-message-wrapper .ba-comments-captcha-wrapper'; 10 $g(str).each(function(){ 11 app.initCommentsRecaptcha(this); 12 }); 13 $g('.ba-login-captcha-wrapper').each(function(){ 14 app.initLoginRecaptcha(this); 15 }); 16}; 17 18var verifyLoginCaptcha = () => { 19 document.querySelectorAll('.login-recaptcha').forEach(function($this){ 20 app[app.login ? 'login' : 'checkoutForm'].removeAlertTooltip($this); 21 }); 22} 23 24if (window.integrations && window.integrations.facebook) { 25 window.fbAsyncInit = () => { 26 app.facebook.initialize(); 27 } 28} 29 30var $g = jQuery, 31 delay = '', 32 itemsInit = [], 33 app = { 34 hash: window.location.hash, 35 view : 'desktop', 36 modules : {}, 37 loading : {}, 38 edit : {}, 39 items : {}, 40 isExternal: function(link){ 41 return link.indexOf('https://') != -1 || link.indexOf('http://') != -1; 42 }, 43 facebook: { 44 load: () => { 45 app.loading.facebook = true; 46 let js = document.createElement('script'); 47 if (document.getElementById('facebook-jssdk')) return; 48 js.id = 'facebook-jssdk'; 49 js.src = "https://connect.facebook.net/en_US/sdk.js"; 50 js.crossorigin = 'anonymous'; 51 document.head.append(js); 52 }, 53 initialize: () => { 54 FB.init({ 55 appId : window.integrations.facebook, 56 autoLogAppEvents : true, 57 xfbml : true, 58 version : 'v14.0' 59 }); 60 }, 61 getUserInfo: (response) => { 62 return new Promise((resolve, reject) => { 63 if (response.status === 'connected') { 64 FB.api('/'+response.authResponse.userID+'/?fields=id,name,email,picture', 'GET', {}, (fields) => { 65 let data = { 66 name: fields.name, 67 email: fields.email, 68 avatar: fields.picture.data.url, 69 id: fields.id 70 } 71 resolve(data); 72 }); 73 } 74 }); 75 } 76 }, 77 google: { 78 load: (callback, selector, options) => { 79 let js = document.createElement('script'); 80 js.src = 'https://accounts.google.com/gsi/client' 81 js.onload = () => { 82 app.google.initialize(callback, selector, options); 83 } 84 document.head.append(js); 85 }, 86 initialize: (callback, selector, options) => { 87 google.accounts.id.initialize({ 88 client_id: window.integrations.google, 89 callback: callback 90 }); 91 setTimeout(() => { 92 document.querySelectorAll(selector).forEach((parent) => { 93 google.accounts.id.renderButton(parent, options); 94 }); 95 }, 1000); 96 }, 97 renderButton: (selector, options) => { 98 document.querySelectorAll(selector).forEach((parent) => { 99 google.accounts.id.renderButton(parent, options); 100 }); 101 }, 102 JSONWebToken: (token) => { 103 let url = token.split('.')[1], 104 base = url.replace(/-/g, '+').replace(/_/g, '/'), 105 json = decodeURIComponent(window.atob(base).split('').map(function(c) { 106 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); 107 }).join('')); 108 109 return JSON.parse(json); 110 }, 111 getUserInfo: function(profile){ 112 let data = { 113 name: profile.name, 114 email: profile.email, 115 avatar: profile.picture, 116 id: profile.sub 117 } 118 119 return data; 120 } 121 }, 122 decimalAdjust: function(type, value, exp){ 123 if (typeof exp === 'undefined' || +exp === 0) { 124 return Math[type](value); 125 } 126 value = +value; 127 exp = +exp; 128 if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) { 129 return NaN; 130 } 131 value = value.toString().split('e'); 132 value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp))); 133 value = value.toString().split('e'); 134 135 return +(value[0]+'e'+(value[1] ? (+value[1] + exp) : exp)); 136 }, 137 strrev: function(string){ 138 let ret = '', i = 0; 139 for (i = string.length - 1; i >= 0; i--) { 140 ret += string[i]; 141 } 142 143 return ret; 144 },
145 renderPrice: function(value, thousand, separator, decimals, rate){ 146 rate = !rate ? 1 : rate; 147 value *= rate; 148 value = app.decimalAdjust('round', value, decimals * -1); 149 value = String(value); 150 let delta = value < 0 ? '-' : '', 151 priceArray = value.replace('-', '').trim().split('.'), 152 priceThousand = priceArray[0], 153 priceDecimal = priceArray[1] ? priceArray[1] : '', 154 price = ''; 155 if (priceThousand.length > 3 && thousand != '') { 156 for (let i = 0; i < priceThousand.length; i++) { 157 if (i % 3 == 0 && i != 0) { 158 price += thousand; 159 } 160 price += priceThousand[priceThousand.length - 1 - i]; 161 } 162 price = app.strrev(price); 163 } else { 164 price += priceThousand; 165 } 166 if (decimals != 0) { 167 price += separator; 168 for (let i = 0; i < decimals; i++) { 169 price += priceDecimal[i] ? priceDecimal[i] : '0'; 170 } 171 } 172 173 return delta+price; 174 }, 175 getObject: function(key){ 176 var object = $g.extend(true, {}, app.items[key].desktop); 177 if (app.view != 'desktop') { 178 for (var ind in breakpoints) { 179 if (!app.items[key][ind]) { 180 app.items[key][ind] = {}; 181 } 182 object = $g.extend(true, {}, object, app.items[key][ind]); 183 if (ind == app.view) { 184 break; 185 } 186 } 187 } 188 189 return object; 190 }, 191 initLoginRecaptcha: function(parent){ 192 if (!recaptchaObject) { 193 194 return false; 195 } 196 let elem = document.createElement('div'), 197 options = { 198 sitekey: recaptchaObject.public_key, 199 callback: verifyLoginCaptcha 200 }; 201 elem.id = 'login-recaptcha-'+(+new Date()); 202 elem.className = 'login-recaptcha'; 203 parent.innerHTML = ''; 204 parent.append(elem); 205 if (parent.dataset.type == 'recaptcha') { 206 options.theme = recaptchaObject.theme; 207 options.size = recaptchaObject.size; 208 } else { 209 options.badge = recaptchaObject.badge; 210 options.size = 'invisible'; 211 parent.classList.add(options.badge+'-style'); 212 } 213 recaptchaObject.data[elem.id] = grecaptcha.render(elem, options); 214 if (parent.dataset.type != 'recaptcha') { 215 grecaptcha.execute(recaptchaObject.data[elem.id]); 216 } 217 }, 218 initCommentsRecaptcha: function(parent){ 219 if (!recaptchaObject) { 220 221 return false; 222 } 223 let elem = document.createElement('div'), 224 options = { 225 sitekey : recaptchaObject.public_key 226 }; 227 elem.id = 'comments-recaptcha-'+(+new Date()); 228 elem.className = 'comments-recaptcha'; 229 parent.innerHTML = ''; 230 parent.append(elem); 231 if (recaptchaObject.type == 'recaptcha') { 232 options.theme = recaptchaObject.theme; 233 options.size = recaptchaObject.size; 234 } else { 235 options.badge = recaptchaObject.badge; 236 options.size = 'invisible'; 237 elem.closest('.ba-comments-captcha-wrapper').classList.add(options.badge+'-style'); 238 } 239 recaptchaObject.data[elem.id] = grecaptcha.render(elem, options); 240 if (recaptchaObject.type != 'recaptcha') { 241 grecaptcha.execute(recaptchaObject.data[elem.id]); 242 } 243 }, 244 hideNotice:function(){ 245 app.notification.classList.remove('notification-in'); 246 app.notification.classList.add('animation-out'); 247 }, 248 checkOverlay: function(obj, key){ 249 $g('.ba-item-overlay-section').each(function(){ 250 $g(this).find('.ba-overlay-section-backdrop').appendTo(document.body); 251 }); 252 }, 253 _: function(key){ 254 if (window.gridboxLanguage && gridboxLanguage[key]) { 255 return gridboxLanguage[key]; 256 } else { 257 return key; 258 } 259 }, 260 checkGridboxPaymentError: function(){ 261 let gridbox_payment_error = localStorage.getItem('gridbox_payment_error'); 262 if (gridbox_payment_error) { 263 app.showNotice(gridbox_payment_error, 'ba-alert'); 264 localStorage.removeItem('gridbox_payment_error'); 265 } 266 }, 267 loadNotice: function(){ 268 return new Promise(function(resolve, reject) { 269 270 fetch(JUri+'components/com_gridbox/libraries/css/plugins/notification.css').then(function(request){ 271 return request.text(); 272 }).then(function(text){ 273 let style = document.createElement('style'); 274 document.head.append(style); 275 style.innerHTML = text; 276 app.notification = document.createElement('div'); 277 app.notification.id = 'ba-notification'; 278 app.notification.innerHTML = '<i class="zmdi zmdi-close"></i><h4>'+app._('ERROR')+'</h4><p></p>'; 279 app.notification.querySelector('.zmdi-close').addEventListener('click', function(){ 280 app.hideNotice(); 281 }); 282 document.body.appendChild(app.notification); 283 resolve(); 284 }); 285 }); 286 }, 287 showNotice: function(message, className){ 288 if (!app.notification) { 289 app.loadNotice().then(() => { 290 app.showNotice(message, className); 291 }); 292 return false;
293 } 294 app.notification.showCallback = function(){}; 295 if (!className) { 296 className = ''; 297 } 298 if (app.notification.classList.contains('notification-in')) { 299 app.notification.showCallback = function(){ 300 app.notification.showCallback = function(){}; 301 app.addNoticeText(message, className); 302 }; 303 } else { 304 app.addNoticeText(message, className); 305 } 306 }, 307 addNoticeText: function(message, className){ 308 var time = 3000; 309 if (className == 'ba-alert') { 310 time = 6000; 311 } 312 app.notification.querySelector('p').innerHTML = message; 313 if (className) { 314 app.notification.classList.add(className); 315 } else { 316 app.notification.classList.remove('ba-alert'); 317 } 318 app.notification.classList.remove('animation-out') 319 app.notification.classList.add('notification-in'); 320 clearTimeout(app.notification.hideDelay); 321 app.notification.hideDelay = setTimeout(function(){ 322 app.hideNotice(); 323 setTimeout(function(){ 324 if (className) { 325 app.notification.classList.remove(className); 326 } 327 app.notification.showCallback(); 328 }, 400); 329 }, time); 330 }, 331 disabledAnimation: { 332 'sticky-header': true, 333 'lightbox': true 334 }, 335 checkAnimation: function(){ 336 app.viewportItems = []; 337 app.motionItems = []; 338 $g('.ba-section, .ba-row, .ba-grid-column').each(function(){ 339 if (!app.items[this.id]) { 340 return; 341 } 342 let object = $g.extend(true, {}, app.items[this.id].desktop.animation); 343 let motion = $g.extend(true, {}, app.items[this.id].desktop.motions ?? {}); 344 let inMotion = false; 345 const canAnimate = !app.disabledAnimation[app.items[this.id].type]; 346 const motions = { 347 desktop: motion 348 }; 349 if (app.view != 'desktop') { 350 for (let ind in breakpoints) { 351 if (!app.items[this.id][ind]) { 352 app.items[this.id][ind] = { 353 animation : {} 354 } 355 } 356 object = $g.extend(true, {}, object, app.items[this.id][ind].animation); 357 if (ind == app.view) { 358 break; 359 } 360 } 361 } 362 for (let ind in breakpoints) { 363 if (!app.items[this.id][ind]) { 364 app.items[this.id][ind] = { 365 animation : {} 366 } 367 } 368 motion = $g.extend(true, {}, motion, app.items[this.id][ind]?.motions ?? motion); 369 motions[ind] = motion; 370 } 371 if (object.effect && canAnimate) { 372 app.viewportItems.push({ 373 animation: object, 374 item: $g(this) 375 }); 376 } else if (!object.effect && canAnimate && $g(this).viewportChecker) { 377 $g(this).viewportChecker(object) 378 } else if (object.effect) { 379 this.classList.add('visible'); 380 } 381 for (let ind in motions) { 382 for (let key in motions[ind]) { 383 if (motions[ind][key].enable) { 384 app.motionItems.push({ 385 motions: motions, 386 item: $g(this) 387 }); 388 inMotion = true; 389 break; 390 } 391 } 392 if (inMotion) { 393 break; 394 } 395 } 396 if ($g(this).motion && !inMotion) { 397 $g(this).motion(motions); 398 } 399 }); 400 $g('.ba-item').each(function(){ 401 if (app.items[this.id] && app.items[this.id].desktop && app.items[this.id].desktop.appearance) { 402 let object = $g.extend(true, {}, app.items[this.id].desktop.appearance), 403 motion = app.items[this.id].desktop.motions ? $g.extend(true, {}, app.items[this.id].desktop.motions) : {}, 404 inMotion = false, 405 motions = { 406 desktop: motion 407 }; 408 if (app.view != 'desktop') { 409 for (let ind in breakpoints) { 410 if (!app.items[this.id][ind]) { 411 app.items[this.id][ind] = { 412 appearance : {} 413 }; 414 } 415 object = $g.extend(true, {}, object, app.items[this.id][ind].appearance);
416 if (ind == app.view) { 417 break; 418 } 419 } 420 } 421 for (let ind in breakpoints) { 422 motion = app.items[this.id][ind].motions ? $g.extend(true, {}, motion, app.items[this.id][ind].motions) : motion; 423 motions[ind] = motion; 424 } 425 if (object.effect) { 426 app.viewportItems.push({ 427 animation: object, 428 item: $g(this) 429 }); 430 } else if (!object.effect && $g(this).viewportChecker) { 431 $g(this).viewportChecker(object) 432 } else if (object.effect) { 433 this.classList.add('visible'); 434 } 435 for (let ind in motions) { 436 for (let key in motions[ind]) { 437 if (motions[ind][key].enable) { 438 app.motionItems.push({ 439 motions: motions, 440 item: $g(this) 441 }); 442 inMotion = true; 443 break; 444 } 445 } 446 if (inMotion) { 447 break; 448 } 449 } 450 if ($g(this).motion && !inMotion) { 451 $g(this).motion(motions); 452 } 453 } 454 }); 455 if (app.viewportItems.length > 0 || app.motionItems.length > 0) { 456 app.checkModule('loadAnimations'); 457 } 458 }, 459 checkModule : function(name, obj){ 460 if (name == 'loadVideoApi' && app.modules[name] && obj && obj.data.type != 'youtube+vimeo' 461 && app.modules[name].data.type != 'youtube+vimeo' && app.modules[name].data.type != obj.data.type) { 462 obj.data.type = 'youtube+vimeo'; 463 } else if (typeof(obj) != 'undefined') { 464 app.modules[name] = obj; 465 } 466 if (typeof(app[name]) == 'undefined' && !app.loading[name]) { 467 app.loading[name] = true; 468 app.loadModule(name); 469 } else if (typeof(app[name]) != 'undefined') { 470 if (typeof(obj) != 'undefined') { 471 app[name](obj.data, obj.selector); 472 } else { 473 app[name](); 474 } 475 } 476 }, 477 checkVideoBackground : function(){ 478 let flag = false; 479 $g('.ba-section, .ba-row, .ba-grid-column').each(function(){ 480 if (app.items[this.id] && app.items[this.id].desktop.background.type == 'video') { 481 flag = true; 482 return false; 483 } 484 }); 485 $g('.ba-item-flipbox').each(function(){ 486 if (app.items[this.id] && app.items[this.id].sides.frontside.desktop.background 487 && app.items[this.id].sides.frontside.desktop.background.type == 'video') { 488 flag = true; 489 return false; 490 } 491 if (app.items[this.id] && app.items[this.id].sides.backside.desktop.background 492 && app.items[this.id].sides.backside.desktop.background.type == 'video') { 493 flag = true; 494 return false; 495 } 496 }); 497 if (app.theme.desktop.background.type == 'video') { 498 flag = true; 499 } 500 if (flag) { 501 app.checkModule('createVideo', {}); 502 } 503 }, 504 loadModule : function(key){ 505 if (key != 'setCalendar' && key != 'defaultElementsStyle' && key != 'gridboxLanguage' && 506 key != 'shapeDividers' && key != 'presetsPatern') { 507 var script = document.createElement('script'); 508 script.src = JUri+'components/com_gridbox/libraries/modules/'+key+'.js?'+gridboxVersion; 509 document.head.append(script); 510 return false;
511 } 512 $g.ajax({ 513 type:"POST", 514 dataType:'text', 515 url:"index.php?option=com_gridbox&task=editor.loadModule&module="+key+"&"+gridboxVersion, 516 data:{ 517 module : key 518 }, 519 complete: function(msg){ 520 let script = document.createElement('script'); 521 document.head.append(script); 522 script.innerHTML = msg.responseText; 523 } 524 }); 525 }, 526 checkView: function(){ 527 var width = $g(window).width(); 528 app.view = 'desktop'; 529 for (var ind in breakpoints) { 530 if (width <= breakpoints[ind]) { 531 app.view = ind; 532 } 533 } 534 }, 535 resize: function(){ 536 clearTimeout(delay); 537 app.checkView(); 538 delay = setTimeout(function(){ 539 if ('setPostMasonryHeight' in window) { 540 $g('.ba-blog-posts-wrapper.ba-masonry-layout').each(function(){ 541 var key = $g(this).closest('.ba-item').attr('id'); 542 setPostMasonryHeight(key); 543 }); 544 } 545 if ('setGalleryMasonryHeight' in window) { 546 $g('.gridbox-gallery-wrapper.simple-gallery-masonry-layout').each(function(){ 547 setGalleryMasonryHeight(this.closest('.ba-item').id); 548 }); 549 } 550 }, 300); 551 }, 552 checkCommentInTabs: function(hash){ 553 $g('a.'+hash.replace('#', '')).first().each(function(){ 554 let tab = this.closest('.tab-pane, .accordion-body'); 555 if (tab && !tab.classList.contains('active') && !tab.classList.contains('in')) { 556 $g('a[href="#'+tab.id+'"]').trigger('click'); 557 } 558 }); 559 }, 560 gridboxLoaded: function(){ 561 app.checkView(); 562 app.checkAnimation(); 563 checkOnePage(); 564 $g(window).on('resize', app.resize); 565 if (!$g('body').hasClass('gridbox')) { 566 $g(window).on('scroll.onepage', checkOnePageActive); 567 } 568 $g(window).on('scroll', function(){ 569 var top = window.pageYOffset; 570 if (!('lastPageYOffset' in window)) { 571 window.lastPageYOffset = top; 572 } 573 $g('header')[top > 40 ? 'addClass' : 'removeClass']('fixed-header'); 574 $g('.ba-sticky-header').each(function(){ 575 this.closest('header, footer, .body').classList.add('ba-sticky-header-parent'); 576 if (this.querySelector('.ba-sticky-header > .ba-section')) { 577 var section = this.querySelector('.ba-sticky-header > .ba-section'), 578 obj = app.items[section.id], 579 offset = obj.desktop.offset; 580 if (app.view != 'desktop') { 581 for (var ind in breakpoints) { 582 if (!obj[ind]) { 583 obj[ind] = {}; 584 } 585 offset = obj[ind].offset ? obj[ind].offset : offset; 586 if (ind == app.view) { 587 break; 588 } 589 } 590 } 591 if (!this.classList.contains('visible-sticky-header')) { 592 if (top >= offset * 1 && 593 (!obj.scrollup || (obj.scrollup && top - window.lastPageYOffset < 0))) { 594 this.classList.add('visible-sticky-header'); 595 document.body.classList.add('sticky-header-opened'); 596 if (obj.desktop.animation.effect) { 597 section.classList.add(obj.desktop.animation.effect); 598 setTimeout(function(){ 599 section.classList.remove(obj.desktop.animation.effect); 600 }, obj.desktop.animation.delay * 1000 + obj.desktop.animation.duration * 1000); 601 } 602 $g(window).trigger('scroll'); 603 } 604 } 605 if ((top < offset * 1 && !obj.scrollup) || (obj.scrollup && (top - window.lastPageYOffset > 0 || top <= offset * 1))) { 606 this.classList.remove('visible-sticky-header'); 607 document.body.classList.remove('sticky-header-opened'); 608 } 609 } 610 }); 611 window.lastPageYOffset = top; 612 }); 613 $g(window).trigger('scroll'); 614 $g('.ba-item [contenteditable]').removeAttr('contenteditable'); 615 if ($g('.ba-item-overlay-section').length > 0) { 616 app.checkModule('checkOverlay'); 617 } 618 $g('.ba-item-main-menu, .ba-item-one-page-menu, .ba-item-overlay-section').each(function(){ 619 if (app.items[this.id]) { 620 var obj = { 621 data : app.items[this.id], 622 selector : this.id 623 }; 624 itemsInit.push(obj); 625 } 626 }); 627 $g('.ba-item').not('.ba-item-main-menu, .ba-item-one-page-menu, .ba-item-overlay-section').each(function(){ 628 if (app.items[this.id]) { 629 var obj = { 630 data : app.items[this.id], 631 selector : this.id 632 }; 633 itemsInit.push(obj); 634 } 635 }); 636 if (itemsInit.length > 0) { 637 itemsInit.reverse(); 638 app.checkModule('initItems', itemsInit.pop()); 639 }
640 app.checkVideoBackground(); 641 $g('.ba-lightbox-backdrop').on('keyup', function(event){ 642 if (event.key == 'Escape') { 643 $g(this).find('.ba-lightbox-close').first().click(); 644 } 645 }).find('.ba-lightbox-close').on('click keyup', function(event){ 646 app.AccessibilityHelper.processAction(event, () => { 647 const lightbox = this.closest('.ba-lightbox-backdrop'); 648 lightboxVideoClose(lightbox); 649 lightbox.classList.remove('visible-lightbox'); 650 app.AccessibilityHelper.releaseTrap(lightbox.querySelector('.ba-wrapper')); 651 document.body.classList.remove('lightbox-open'); 652 }); 653 }); 654 $g('.ba-lightbox-backdrop').each(function(){ 655 let obj = app.items[this.dataset.id]; 656 if (obj.type == 'cookies' || !obj.session.enable) { 657 initLightbox(this, obj); 658 } else { 659 let flag = true; 660 if (localStorage[this.dataset.id]) { 661 let date = new Date().getTime(), 662 expires = new Date(localStorage[this.dataset.id]); 663 expires.getTime(); 664 if (date >= expires) { 665 flag = true; 666 localStorage.removeItem(this.dataset.id); 667 } else { 668 flag = false; 669 } 670 } 671 if (flag) { 672 let expiration = new Date(); 673 expiration.setDate(expiration.getDate() + obj.session.duration * 1); 674 localStorage.setItem(this.dataset.id, expiration); 675 initLightbox(this, obj); 676 } 677 } 678 }); 679 $g('.ba-section, .ba-row, .ba-grid-column').each(function(){ 680 if (app.items[this.id] && app.items[this.id].parallax && app.items[this.id].parallax.enable) { 681 app.checkModule('loadParallax'); 682 return false; 683 } 684 }); 685 if (document.querySelector('.open-calendar-dialog')) { 686 app.loadModule('calendar'); 687 } 688 } 689 }; 690 691app.fetch = async function(url, data, isFile) { 692 const module = await import(`${JUri}components/com_gridbox/assets/modules/Request.js`) 693 694 return await module.default.post(url, data, isFile); 695} 696 697app.getFormData = async function(data, isFile) { 698 const module = await import(`${JUri}components/com_gridbox/assets/modules/Request.js`) 699 700 return await module.default.getBody(data, isFile); 701} 702 703app.preloaded = { 704 total: 0, 705 loaded: 0, 706 loadGridbox: function(){ 707 app.lazyLoad ? app.lazyLoad.check() : ''; 708 app.preloaded.end = true; 709 app.gridboxLoaded(); 710 }, 711 callback: function(){ 712 app.preloaded.loaded++; 713 if (app.preloaded.total <= app.preloaded.loaded && !app.preloaded.end && document.readyState != 'loading') { 714 app.preloaded.loadGridbox(); 715 } 716 } 717} 718 719document.querySelectorAll('link[rel="preload"][as="style"]').forEach(function(link){ 720 link.onload = app.preloaded.callback; 721 link.onerror = app.preloaded.callback; 722 app.preloaded.total++; 723}); 724 725class CustomSelect { 726 constructor(element) 727 { 728 this.$select = $g(element); 729 this.$textInput = this.$select.find('input[type="text"]'); 730 this.$hiddenInput = this.$select.find('input[type="hidden"]'); 731 this.$list = this.$select.find('ul'); 732 733 this.currentIndex = -1; 734 735 this.setupAria(); 736 this.attachEvents(); 737 } 738 739 getOptions() 740 { 741 return this.$list.find('li'); 742 } 743 744 setupAria() 745 { 746 const listId = 'listbox-' + Math.random().toString(36).substr(2, 6); 747 748 this.$select.attr({ 749 'role': 'combobox', 750 'aria-haspopup': 'listbox', 751 'aria-expanded': 'false', 752 }); 753 754 this.$list.attr({ 755 'role': 'listbox', 756 'tabindex': '-1', 757 'id': listId 758 }); 759 760 this.$textInput.attr({ 761 'readonly': 'true', 762 'aria-controls': listId 763 }); 764 } 765 766 attachEvents() 767 { 768 this.$select.on('click', 'i, input', () => { 769 if (!this.$list.hasClass('visible-select')) { 770 setTimeout(() => this.openList(), 100); 771 } 772 }); 773 774 this.$select.on('click', 'li', (event) => { 775 const index = this.getOptions().index(event.currentTarget); 776 this.selectOption(index); 777 }); 778
779 this.$select.on('keydown', (e) => this.handleKeydown(e)); 780 } 781 782 openList() 783 { 784 const options = this.getOptions(); 785 this.$list.addClass('visible-select'); 786 this.$select.attr('aria-expanded', 'true'); 787 788 options.removeClass('focused'); 789 790 const selectedIndex = options.index(options.filter('.selected')); 791 this.currentIndex = selectedIndex >= 0 ? selectedIndex : 0; 792 793 if (options.length > 0) { 794 options.eq(this.currentIndex).addClass('focused'); 795 } 796 797 this.$select.trigger('show'); 798 } 799 800 closeList() 801 { 802 this.$list.removeClass('visible-select'); 803 this.$select.attr('aria-expanded', 'false'); 804 this.getOptions().removeClass('focused'); 805 } 806 807 selectOption(index) 808 { 809 const options = this.getOptions(); 810 const $opt = options.eq(index); 811 812 options.removeClass('selected'); 813 $opt.addClass('selected'); 814 815 this.$textInput.val($opt.text().trim()); 816 this.$hiddenInput.val($opt.data('value')).trigger('change'); 817 818 this.currentIndex = index; 819 820 this.$select.trigger('customAction'); 821 this.closeList(); 822 } 823 824 handleKeydown(e) 825 { 826 const options = this.getOptions(); 827 if (options.length === 0) return; 828 829 if (e.key === ' ' || e.key === 'Enter') { 830 e.preventDefault(); 831 if (!this.$list.hasClass('visible-select')) { 832 this.openList(); 833 } else { 834 this.selectOption(this.currentIndex); 835 } 836 } else if (e.key === 'ArrowDown') { 837 e.preventDefault(); 838 if (!this.$list.hasClass('visible-select')) { 839 this.openList(); 840 } else { 841 this.currentIndex = (this.currentIndex + 1) % options.length; 842 this.updateFocus(); 843 } 844 } else if (e.key === 'ArrowUp') { 845 e.preventDefault(); 846 if (!this.$list.hasClass('visible-select')) { 847 this.openList(); 848 } else { 849 this.currentIndex = (this.currentIndex - 1 + options.length) % options.length; 850 this.updateFocus(); 851 } 852 } else if (e.key === 'Escape') { 853 this.closeList(); 854 } 855 } 856 857 updateFocus() 858 { 859 const options = this.getOptions(); 860 options.removeClass('focused'); 861 options.eq(this.currentIndex).addClass('focused'); 862 } 863 864 static initAll(selector = '.ba-custom-select') 865 { 866 $g(selector).each(function () { 867 new CustomSelect(this); 868 }); 869 } 870} 871 872document.addEventListener("DOMContentLoaded", function(){ 873 $g('link[rel="preload"][as="style"]').attr('rel', 'stylesheet'); 874 document.body.style.opacity = ''; 875 document.body.style.overflow = ''; 876 document.body.style.margin = ''; 877 let preloader = document.querySelector('.ba-item-preloader'); 878 if (preloader) { 879 setTimeout(function(){ 880 preloader.classList.add('preloader-animation-out'); 881 app.checkGridboxPaymentError(); 882 }, preloader.dataset.delay * 1000); 883 } else { 884 app.checkGridboxPaymentError(); 885 } 886 if ('setPostMasonryHeight' in window) { 887 $g('.ba-blog-posts-wrapper.ba-masonry-layout').each(function(){ 888 var key = $g(this).closest('.ba-item').attr('id'); 889 setPostMasonryHeight(key); 890 }); 891 } 892 if ('setGalleryMasonryHeight' in window) { 893 $g('.gridbox-gallery-wrapper.simple-gallery-masonry-layout').each(function(){ 894 setGalleryMasonryHeight(this.closest('.ba-item').id); 895 }); 896 } 897 if (app.hash == '#total-count-wrapper' || app.hash == '#total-reviews-count-wrapper') { 898 let item = $g('a.'+app.hash.replace('#', '')); 899 app.checkCommentInTabs(app.hash); 900 app.scrollIntoView(item); 901 } 902 $g('body').on('click', function(){ 903 $g('.visible-select').removeClass('visible-select'); 904 if (app.storeSearch && app.storeSearch.visible) { 905 app.storeSearch.clearSearch(); 906 } 907 }).on('hide', '.modal', function(){ 908 this.classList.add('ba-modal-close'); 909 setTimeout(function(){ 910 $g('.ba-modal-close').removeClass('ba-modal-close'); 911 }, 500); 912 }); 913 914 CustomSelect.initAll(); 915 916 $g('.intro-post-reviews a, .intro-post-comments a').on('click', function(){ 917 let item = $g('a.'+this.hash.replace('#', '')); 918 app.checkCommentInTabs(this.hash); 919 app.scrollIntoView(item); 920 }); 921 $g('li.megamenu-item').on('mouseenter', function(){ 922 var rectangle = this.getBoundingClientRect(), 923 left = rectangle.left * -1, 924 wrapper = $g(this).find(' > div.tabs-content-wrapper'), 925 width = document.documentElement.clientWidth, 926 maxwidth = width - rectangle.right; 927 if (wrapper.hasClass('megamenu-center') && wrapper.hasClass('ba-container')) { 928 left = $g(this).width() / 2; 929 } 930 if (rectangle.left < maxwidth) { 931 maxwidth = rectangle.left; 932 } 933 if (!wrapper.hasClass('megamenu-center')) { 934 maxwidth = width - rectangle.left; 935 } else if (wrapper.hasClass('ba-container')) { 936 left -= wrapper.outerWidth() / 2; 937 } 938 if (wrapper.hasClass('megamenu-center')) { 939 maxwidth = (maxwidth + (rectangle.right - rectangle.left) / 2) * 2; 940 } 941 if ($g(this).closest('.ba-menu-wrapper').hasClass('vertical-menu')) { 942 maxwidth = width - rectangle.right; 943 } 944 wrapper.css({ 945 'margin-left' : left+'px', 946 'width' : width+'px', 947 'max-width' : maxwidth+'px' 948 }); 949 }); 950 $g('.ba-item-main-menu').closest('.ba-row').addClass('row-with-menu'); 951 for (var key in gridboxItems) { 952 if (key != 'theme') { 953 app.items = $g.extend(true, app.items, gridboxItems[key]); 954 } 955 } 956 app.theme = gridboxItems.theme; 957 if (app.preloaded.total == 0) { 958 app.gridboxLoaded(); 959 } else if (app.preloaded.total <= app.preloaded.loaded && !app.preloaded.end) { 960 app.preloaded.loadGridbox(); 961 } 962}); 963 964var lightboxVideo = {}; 965 966function lightboxVideoClose(item) 967{ 968 var iframes = item.querySelectorAll('.ba-item-custom-html iframe, .ba-item-video iframe'); 969 for (var i = 0; i < iframes.length; i++) { 970 var src = iframes[i].src, 971 videoId = iframes[i].id; 972 if (src && src.indexOf('youtube.com') !== -1 && 'pauseVideo' in lightboxVideo[videoId]) { 973 lightboxVideo[videoId].pauseVideo(); 974 } else if (src && src.indexOf('vimeo.com') !== -1 && 'pause' in lightboxVideo[videoId]) { 975 lightboxVideo[videoId].pause(); 976 } 977 } 978 iframes = item.querySelectorAll('.ba-item-video video, .ba-item-custom-html video'); 979 for (var i = 0; i < iframes.length; i++) { 980 var videoId = iframes[i].id; 981 lightboxVideo[videoId].pause(); 982 } 983} 984 985function lightboxVideoOpen(item) 986{
987 if (item.querySelectorAll('.video-lazy-load-thumbnail')) { 988 $g(item).find('.video-lazy-load-thumbnail').trigger('click'); 989 } 990 var iframes = item.querySelectorAll('.ba-item-custom-html iframe, .ba-item-video iframe'), 991 youtube = false, 992 vimeo = false, 993 id = +new Date(); 994 for (var i = 0; i < iframes.length; i++) { 995 var src = iframes[i].src, 996 videoId; 997 if (src && src.indexOf('youtube.com') !== -1) { 998 if (!app.youtube) { 999 youtube = true; 1000 } else { 1001 if (src.indexOf('enablejsapi=1') === -1) { 1002 if (src.indexOf('?') === -1) { 1003 src += '?'; 1004 } else { 1005 src += '&' 1006 } 1007 src += 'enablejsapi=1'; 1008 iframes[i].src = src; 1009 } 1010 if (!iframes[i].id) { 1011 iframes[i].id = id++; 1012 } 1013 videoId = iframes[i].id; 1014 if (!lightboxVideo[videoId] || !('playVideo' in lightboxVideo[videoId])) { 1015 lightboxVideo[videoId] = new YT.Player(videoId, { 1016 events: { 1017 onReady: function(event){ 1018 lightboxVideo[videoId].playVideo(); 1019 } 1020 } 1021 }); 1022 } else { 1023 lightboxVideo[videoId].playVideo(); 1024 } 1025 } 1026 } else if (src && src.indexOf('vimeo.com') !== -1) { 1027 if (!app.vimeo) { 1028 vimeo = true; 1029 } else { 1030 if (!iframes[i].id) { 1031 iframes[i].id = id++; 1032 } 1033 videoId = iframes[i].id; 1034 if (!lightboxVideo[videoId] || !('play' in lightboxVideo[videoId])) { 1035 src = src.split('/'); 1036 src = src.slice(-1); 1037 src = src[0].split('?'); 1038 src = src[0]; 1039 var options = { 1040 id: src * 1, 1041 loop: true, 1042 }; 1043 lightboxVideo[videoId] = new Vimeo.Player(videoId, options); 1044 } 1045 lightboxVideo[videoId].play(); 1046 } 1047 } 1048 } 1049 iframes = item.querySelectorAll('.ba-item-video video, .ba-item-custom-html video'); 1050 for (var i = 0; i < iframes.length; i++) { 1051 if (!iframes[i].id) { 1052 iframes[i].id = id++; 1053 } 1054 videoId = iframes[i].id; 1055 if (!lightboxVideo[videoId]) { 1056 lightboxVideo[videoId] = iframes[i]; 1057 } 1058 lightboxVideo[videoId].play(); 1059 } 1060 if (youtube || vimeo) { 1061 var object = { 1062 data : {} 1063 }; 1064 if (youtube && !vimeo) { 1065 object.data.type = 'youtube'; 1066 } else if (vimeo && !youtube) { 1067 object.data.type = 'vimeo'; 1068 } else { 1069 object.data.type = 'youtube+vimeo'; 1070 } 1071 app.checkModule('loadVideoApi', object); 1072 } 1073 if (youtube) { 1074 lightboxVideo.overlay = item; 1075 } else if (vimeo) { 1076 lightboxVideo.overlay = item; 1077 } 1078 1079 return !youtube && !vimeo; 1080} 1081 1082function initLightbox($this, obj) 1083{ 1084 var obj = app.items[$this.dataset.id]; 1085 if (obj.type == 'cookies') { 1086 if (localStorage['ba-item-cookie']) { 1087 return false; 1088 } 1089 $g($this).find('.ba-item-button[data-cookie="accept"]').on('click', function(event){ 1090 event.preventDefault(); 1091 localStorage.setItem('ba-item-cookie', 'accept'); 1092 $g(this).closest('.ba-lightbox-backdrop').removeClass('visible-lightbox'); 1093 $g('body').removeClass('lightbox-open'); 1094 }); 1095 showLightbox($this); 1096 } else if (obj.trigger.type == 'time-delay') { 1097 setTimeout(function(){ 1098 showLightbox($this); 1099 }, obj.trigger.time); 1100 } else if (obj.trigger.type == 'scrolling') { 1101 lightboxScroll($this, obj.trigger.scroll * 1); 1102 } else if (obj.trigger.type == 'exit-intent') { 1103 $g(document).one('mouseleave.ba-lightbox'+$this.dataset.id, function(){ 1104 showLightbox($this); 1105 }); 1106 } else { 1107 lightboxScroll($this, 100); 1108 } 1109} 1110 1111function lightboxScroll($this, scroll) 1112{ 1113 let top, docHeight, htmlHeight; 1114 $g(window).on('scroll.ba-lightbox'+$this.dataset.id+' load.ba-lightbox'+$this.dataset.id, function(){ 1115 top = $g(window).scrollTop(); 1116 docHeight = document.documentElement.clientHeight 1117 htmlHeight = Math.max( 1118 document.body.scrollHeight, document.documentElement.scrollHeight, 1119 document.body.offsetHeight, document.documentElement.offsetHeight, 1120 document.body.clientHeight, document.documentElement.clientHeight 1121 ); 1122 let x = (docHeight + top) * 100 / htmlHeight; 1123 if (x >= scroll || (scroll > 97 && x >= 97)) { 1124 $g(window).off('scroll.ba-lightbox'+$this.dataset.id+' load.ba-lightbox'+$this.dataset.id); 1125 showLightbox($this); 1126 } 1127 }); 1128} 1129 1130function showLightbox($this) 1131{ 1132 const obj = app.getObject($this.dataset.id); 1133 if (!lightboxVideoOpen($this) || obj.disable == 1) { 1134 return false;
1135 } 1136 const section = $this.querySelector(':scope > .ba-wrapper > .ba-section') 1137 $this.querySelector('.close-lightbox .ba-lightbox-close')?.setAttribute('tabindex', 0); 1138 $this.classList.add('visible-lightbox'); 1139 1140 if (obj.animation.effect) { 1141 section.classList.add(obj.animation.effect); 1142 setTimeout(function(){ 1143 section.classList.remove(obj.animation.effect); 1144 }, obj.animation.delay * 1000 + obj.animation.duration * 1000); 1145 } 1146 1147 if (obj.position == 'lightbox-center') { 1148 document.body.classList.add('lightbox-open'); 1149 } 1150 if (app.AccessibilityHelper) { 1151 app.AccessibilityHelper.trapFocus($this.querySelector('.ba-wrapper'), 350); 1152 } 1153} 1154 1155function compileOnePageValue(item) 1156{ 1157 if (item.length == 0) { 1158 return 0; 1159 } 1160 var value = item.offset().top, 1161 header = $g('header.header'), 1162 comp = header[0] ? getComputedStyle(header[0]) : {}, 1163 top = window.pageYOffset, 1164 stickies = $g('.ba-sticky-header'), 1165 sticky = 0; 1166 if (item.closest('.ba-wrapper').parent().hasClass('header')) { 1167 value = 0; 1168 } else { 1169 stickies.each(function(){ 1170 if (this.offsetHeight > 0) { 1171 let section = this.querySelector('.ba-sticky-header > .ba-section'), 1172 obj = app.items[section.id], 1173 offset = obj ? obj.desktop.offset : 0; 1174 if (app.view != 'desktop') { 1175 for (var ind in breakpoints) { 1176 if (!obj[ind]) { 1177 obj[ind] = {}; 1178 } 1179 offset = obj[ind].offset ? obj[ind].offset : offset; 1180 if (ind == app.view) { 1181 break; 1182 } 1183 } 1184 } 1185 if (obj && ((!obj.scrollup && offset < value) || (obj.scrollup && offset < value && value < top))) { 1186 sticky = this.offsetHeight > sticky ? this.offsetHeight : sticky; 1187 } 1188 } 1189 }); 1190 if ((!header.hasClass('sidebar-menu') || (app.view != 'desktop' && app.view != 'laptop')) 1191 && comp.position == 'fixed') { 1192 sticky = header[0].offsetHeight > sticky ? header[0].offsetHeight : sticky; 1193 if (header.find('.resizing-header').length > 0) { 1194 var resizingSection = getComputedStyle(header.find('.resizing-header')[0]); 1195 value += resizingSection.paddingTop.replace('px', '') * 1; 1196 value += resizingSection.paddingBottom.replace('px', '') * 1; 1197 } 1198 } 1199 value -= sticky; 1200 } 1201 1202 return Math.ceil(value); 1203} 1204 1205function checkOnePage() 1206{ 1207 var alias = location.hash.replace('#', ''); 1208 alias = decodeURIComponent(alias); 1209 if (alias && document.querySelector('.main-menu a[data-alias="'+alias+'"]')) { 1210 $g('.main-menu a[data-alias="'+alias+'"]').each(function(){ 1211 const id = (this.dataset.anchor || this.hash).replace('#', ''); 1212 let item = $g('#' + id); 1213 if ($g(this.parentNode).height() > 0 && id && item.length > 0) { 1214 $g(this).closest('ul').find('.active').removeClass('active'); 1215 $g('.main-menu ul.nav.menu').find(`a[href*="#${id}"], a[data-anchor="${id}"]`) 1216 .parent().addClass('active'); 1217 app.scrollIntoView(item); 1218 return false; 1219 } 1220 }); 1221 } else if ((alias == 'total-reviews-count-wrapper' || alias == 'total-count-wrapper') 1222 && document.querySelector('a.'+alias)) { 1223 let item = $g('a.'+alias); 1224 app.scrollIntoView(item); 1225 } else { 1226 checkOnePageActive(); 1227 } 1228} 1229 1230app.scrollIntoView = function(item){ 1231 let value = compileOnePageValue(item); 1232 if (window.pageYOffset != value) { 1233 $g('html, body').stop().animate({ 1234 'scrollTop' : value 1235 }, 1000); 1236 } 1237} 1238 1239window.onePageScroll = true; 1240 1241function checkOnePageActive() 1242{ 1243 if (!window.onePageScroll) { 1244 return; 1245 } 1246 var items = [], 1247 alias = '', 1248 replace = null, 1249 flag = false;
1250 $g('.main-menu ul li a[data-alias]').each(function(){ 1251 const id = this.dataset.anchor ? '#' + this.dataset.anchor : this.hash; 1252 if (this.offsetHeight > 0 && id && $g(id).height() > 0) { 1253 var computed = getComputedStyle(document.querySelector(id)); 1254 if (computed.display != 'none') { 1255 items.push(this); 1256 } 1257 } 1258 }); 1259 items.sort(function(item1, item2){ 1260 var target1 = $g(item1.dataset.anchor ? '#' + item1.dataset.anchor : item1.hash), 1261 target2 = $g(item2.dataset.anchor ? '#' + item2.dataset.anchor : item2.hash), 1262 top1 = target1.closest('header.header').length == 0 ? target1.offset().top : 0, 1263 top2 = target2.closest('header.header').length == 0 ? target2.offset().top : 0; 1264 if (top1 > top2) { 1265 return 1; 1266 } else if (top1 < top2) { 1267 return -1; 1268 } else { 1269 return 0; 1270 } 1271 }); 1272 let url = '' 1273 for (var i = items.length - 1; i >= 0; i--) { 1274 alias = items[i].dataset.alias; 1275 if (decodeURI(window.location.hash) == '#'+alias) { 1276 replace = location.href.replace(window.location.hash, ''); 1277 } 1278 const id = (items[i].dataset.anchor || items[i].hash).replace('#', '') 1279 const item = $g('#' + id); 1280 let value = compileOnePageValue(item); 1281 if (value <= Math.ceil(window.pageYOffset) + 1) { 1282 flag = true; 1283 url = location.href.replace(window.location.hash, '')+'#'+alias; 1284 $g('.main-menu ul').find(`a[href*="#${id}"], a[data-anchor="${id}"]`) 1285 .closest('ul') 1286 .find('.active').removeClass('active current'); 1287 $g('.main-menu ul').find(`a[href*="#${id}"], a[data-anchor="${id}"]`) 1288 .parent().addClass('active'); 1289 break; 1290 } 1291 } 1292 if (!flag) { 1293 $g('.main-menu ul.nav.menu .active').removeClass('active'); 1294 replace ? window.history.replaceState(null, null, replace) : ''; 1295 } else if (decodeURI(window.location.hash) != '#'+alias) { 1296 window.history.replaceState(null, null, url); 1297 } 1298} 1299 1300window.addEventListener('resize', function(){ 1301 document.documentElement.style.setProperty('--vh', window.innerHeight * 0.01+'px'); 1302}); 1303 1304jQuery(window).on('popstate.onepage', function(){ 1305 window.onePageScroll = false; 1306 setTimeout(function(){ 1307 window.onePageScroll = true; 1308 }, 300); 1309}); 1310 1311/* 1312 Default joomla 1313*/ 1314 1315document.addEventListener('DOMContentLoaded', function(){ 1316 ImportHelper.resolve('AccessibilityHelper', '').then(module => { 1317 /** @type {typeof import('../../../components/com_gridbox/assets/modules/AccessibilityHelper.js').default} */ 1318 app.AccessibilityHelper = module; 1319 }); 1320 document.documentElement.style.setProperty('--vh', window.innerHeight * 0.01+'px'); 1321 $g('*[rel=tooltip]').tooltip(); 1322 $g('.radio.btn-group label').addClass('btn'); 1323 $g('fieldset.btn-group').each(function() { 1324 if (this.disabled) { 1325 $g(this).css('pointer-events', 'none').off('click'); 1326 $g(this).find('.btn').addClass('disabled'); 1327 } 1328 }); 1329 $g(".btn-group label:not(.active)").click(function(){ 1330 var label = $g(this), 1331 input = $g('#'+label.attr('for')); 1332 if (!this.checked) { 1333 label.closest('.btn-group').find("label").removeClass('active btn-success btn-danger btn-primary'); 1334 if (input.val() == '') { 1335 label.addClass('active btn-primary'); 1336 } else if (input.val() == 0) { 1337 label.addClass('active btn-danger'); 1338 } else { 1339 label.addClass('active btn-success'); 1340 } 1341 input.prop('checked', true).trigger('change'); 1342 } 1343 }); 1344 $g(".btn-group input[checked=checked]").each(function(){ 1345 if (this.value == '') { 1346 $g("label[for="+this.id+"]").addClass('active btn-primary'); 1347 } else if (this.value == 0) { 1348 $g("label[for="+this.id+"]").addClass('active btn-danger'); 1349 } else { 1350 $g("label[for="+this.id+"]").addClass('active btn-success'); 1351 } 1352 }); 1353});
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.