1/** FOXIZ MAN SCRIPT */ 2var FOXIZ_MAIN_SCRIPT = (function (Module, $) { 3 'use strict'; 4 5 Module.initParams = function () { 6 this.yesStorage = this.isStorageAvailable(); 7 this.themeSettings = typeof foxizParams !== 'undefined' ? foxizParams : {}; 8 this.galleriesData = typeof foxizGalleriesData !== 'undefined' ? foxizGalleriesData : {}; 9 this.ajaxURL = typeof foxizCoreParams !== 'undefined' ? foxizCoreParams.ajaxurl || '' : ''; 10 this.ajaxData = {}; 11 this.siteAccessFlag = false; 12 this._document = $(document); 13 this._body = $('body'); 14 this._window = $(window); 15 this.html = $('html, body'); 16 this.outerHTML = $('html'); 17 this.iOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent); 18 this.wPoint = {}; 19 this.sticky = {}; 20 this.eSticky = {}; 21 this.YTPlayers = {}; 22 this.articleData = []; 23 this.readIndicatorPercent = 0; 24 this.isProgress = false; 25 this.readIndicator = $('#reading-progress'); 26 this.popupNewsletterEl = $('#rb-popup-newsletter'); 27 28 this.personalizeUID = (typeof FOXIZ_CORE_SCRIPT !== "undefined" && FOXIZ_CORE_SCRIPT.personalizeUID !== undefined) 29 ? FOXIZ_CORE_SCRIPT.personalizeUID 30 : 'u0'; 31 } 32 33 Module.init = function () { 34 this.initParams(); 35 this.syncLayoutLike(); 36 this.topSpacing(); 37 this.siteAccessDetector(); 38 this.headerDropdown(); 39 this.mobileCollapse(); 40 this.initSubMenuPos(); 41 this.privacyTrigger(); 42 this.popupNewsletter(); 43 this.documentClick(); 44 this.backTop(); 45 this.readIndicatorInit(); 46 this.fontResizer(); 47 this.breakingNews(); 48 this.sequentialGalleryDisplay(); 49 this.sliders(); 50 this.carousels(); 51 this.liveSearch(); 52 this.personalizeBlocks(); 53 this.personalizeCategories(); 54 this.likeToggle(); 55 this.singleInfiniteLoadNext(); 56 this.loginPopup(); 57 this.popupTemplate(); 58 this.loadYoutubeIframe(); 59 this.browserResize(); 60 this.footerSlideUp(); 61 this.cartNotification(); 62 this.newsNotification(); 63 this.tocToggle(); 64 this.delayLoad(); 65 this.showPostComment(); 66 this.replyReview(); 67 this.paginationNextPrev(); 68 this.paginationLoadMore(); 69 this.paginationInfinite(); 70 this.productQuantity(); 71 this.readingCollect(); 72 this.liveBlog(); 73 this.neededReloadFuncs(); 74 } 75 76 Module.neededReloadFuncs = function () { 77 this.hoverTipsy(); 78 this.scrollToComment(); 79 this.usersRating(); 80 this.singleGallery(); 81 this.floatingVideo(); 82 this.videoPreview(); 83 this.floatingVideoRemove(); 84 this.scrollTableContent(); 85 this.singleScrollRefresh(); 86 this.playerAutoPlay(); 87 this.hoverEffects(); 88 this.highlightShares(); 89 this.galleryLightbox(); 90 this.singleFeaturedLightbox(); 91 this.accordion(); 92 this.resIframeClassic(); 93 this.taxBasedAccordion(); 94 this.scrollBarSlider(); 95 } 96 97 Module.reInitAll = function () { 98 99 this._window.trigger('load'); 100 this.syncLayoutLike(); 101 if (typeof FOXIZ_PERSONALIZE !== 'undefined') { 102 FOXIZ_PERSONALIZE.syncPersonalizeLayout(); 103 } 104 if (typeof RB_REACTION !== 'undefined') { 105 RB_REACTION.syncReactLayout(); 106 } 107 this.neededReloadFuncs(); 108 Waypoint.refreshAll(); 109 } 110 111 /** sync layout & reload features */ 112 Module.reloadBlockFunc = function () { 113 this._window.trigger('load'); 114 115 if (typeof FOXIZ_PERSONALIZE !== 'undefined') { 116 FOXIZ_PERSONALIZE.syncLayoutBookmarks(); 117 } 118 this.syncLayoutLike(); 119 this.videoPreview(); 120 this.hoverTipsy(); 121 Waypoint.refreshAll(); 122 } 123 124 Module.initElementor = function () { 125 if ('undefined' !== typeof initDarkMode && !FOXIZ_MAIN_SCRIPT.editorDarkModeInit) { 126 FOXIZ_MAIN_SCRIPT.editorDarkModeInit = true; 127 initDarkMode(); 128 } 129 FOXIZ_MAIN_SCRIPT.breakingNews(); 130 FOXIZ_MAIN_SCRIPT.carousels(); 131 FOXIZ_MAIN_SCRIPT.sliders(); 132 } 133 134 Module.isRTL = function () { 135 return this._body.hasClass('rtl'); 136 } 137 138 Module.animationFrame = function (callback) { 139 const func = window.requestAnimationFrame || window.mozRequestAnimationFrame || 140 window.webkitRequestAnimationFrame || this.animationFrameFallback 141 func.call(window, callback) 142 } 143 144 Module.animationFrameFallback = function (callback) { 145 window.setTimeout(callback, 1000 / 60) 146 } 147 148 /** 149 * 150 * @returns {boolean} 151 */ 152 Module.isStorageAvailable = function () { 153 let storage; 154 try { 155 storage = window['localStorage']; 156 storage.setItem('__rbStorageSet', 'x'); 157 storage.removeItem('__rbStorageSet'); 158 return true; 159 } catch (e) { 160 return false; 161 } 162 } 163 164 /** 165 * set localStorage 166 * @param key 167 * @param data 168 */ 169 Module.setStorage = function (key, data) { 170 this.yesStorage && localStorage.setItem(key, typeof data === 'string' ? data : JSON.stringify(data)); 171 } 172 173 /** 174 * get localStorage 175 * @param key 176 * @param defaultValue 177 * @returns {any} 178 */ 179 Module.getStorage = function (key, defaultValue) { 180 if (!this.yesStorage) return null; 181 const data = localStorage.getItem(key); 182 if (data === null) return defaultValue; 183 try { 184 return JSON.parse(data); 185 } catch (e) { 186 return data; 187 } 188 } 189 190 /** 191 * delelte localStorage 192 * @param key 193 */ 194 Module.deleteStorage = function (key) { 195 this.yesStorage && localStorage.removeItem(key); 196 } 197 198 /** 199 * 200 * @param id 201 * @param value 202 * @param ttl 203 * @constructor 204 */ 205 Module.SetTTLStorage = function (id, value, ttl) { 206 const data = { 207 value: value, 208 ttl: Date.now() + ttl * 3600000 209 }; 210 211 this.setStorage(id, data); 212 } 213 214 /** 215 * 216 * @param id 217 * @returns {null|*} 218 */ 219 Module.getTTLStorage = function (id) { 220
221 const data = this.getStorage(id); 222 if (data && Date.now() <= data.ttl) { 223 return data.value; 224 } 225 this.deleteStorage(id); 226 return null; 227 }; 228 229 /** on load */ 230 Module.delayLoad = function () { 231 const self = this; 232 setTimeout(function () { 233 self.stickyNavBar(); 234 self.stickyHeaderBuilder(); 235 }, 100) 236 } 237 238 /** resize */ 239 Module.browserResize = function () { 240 const self = this; 241 242 self._window.on('resize', function () { 243 self.topSpacing(); 244 self.calcSubMenuPos(); 245 }) 246 } 247 248 /* ================================ HEADERS ================================ */ 249 Module.hoverTipsy = function () { 250 251 if (!$.fn.rbTipsy) { 252 return false; 253 } 254 255 this._body.find('[data-copy]').rbTipsy({ 256 title: 'data-copy', 257 fade: true, 258 opacity: 1, 259 trigger: 'hover', 260 gravity: 's' 261 }); 262 263 if (window.innerWidth > 1024) { 264 this._body.find('#site-header [data-title]').rbTipsy({ 265 title: 'data-title', 266 fade: true, 267 opacity: 1, 268 trigger: 'hover', 269 gravity: 'n' 270 }); 271 272 this._body.find('.site-wrap [data-title]').rbTipsy({ 273 title: 'data-title', 274 fade: true, 275 opacity: 1, 276 trigger: 'hover', 277 gravity: 's' 278 }); 279 } 280 } 281 282 /** font resizer */ 283 Module.fontResizer = function () { 284 const self = this; 285 let size = self.yesStorage ? sessionStorage.getItem('rubyResizerStep') : 1; 286 287 self._body.on('click', '.font-resizer-trigger', function (e) { 288 e.preventDefault(); 289 e.stopPropagation(); 290 size++; 291 if (3 < size) { 292 size = 1; 293 self._body.removeClass('medium-entry-size big-entry-size') 294 } else { 295 if (2 == size) { 296 self._body.addClass('medium-entry-size').removeClass('big-entry-size'); 297 } else { 298 self._body.addClass('big-entry-size').removeClass('medium-entry-size') 299 } 300 } 301 302 self.yesStorage && sessionStorage.setItem('rubyResizerStep', size); 303 }); 304 } 305 306 /** hover */ 307 Module.hoverEffects = function () { 308 const selectors = $('.effect-fadeout'); 309 310 if (selectors.length === 0) { 311 return; 312 } 313 selectors.off('mouseenter mouseleave').on('mouseenter', function (e) { 314 e.stopPropagation(); 315 const target = $(this); 316 if (!target.hasClass('activated')) { 317 target.addClass('activated'); 318 } 319 }).on('mouseleave', function () { 320 $(this).removeClass('activated'); 321 }); 322 } 323 324 Module.videoPreview = function () { 325 let playPromise; 326 327 $('.preview-trigger').on('mouseenter', function () { 328 const target = $(this); 329 const wrap = target.find('.preview-video'); 330 if (!wrap.hasClass('video-added')) { 331 const video = '<video preload="auto" muted loop><source src="' + wrap.data('source') + '" type="' + wrap.data('type') + '"></video>'; 332 wrap.append(video).addClass('video-added'); 333 } 334 target.addClass('show-preview'); 335 wrap.css('z-index', 3); 336 const el = target.find('video')[0]; 337 if (el) {
338 playPromise = el.play(); 339 } 340 }).on('mouseleave', function () { 341 const target = $(this); 342 target.find('.preview-video').css('z-index', 1); 343 const el = target.find('video')[0]; 344 if (el && playPromise !== undefined) { 345 playPromise.then(_ => { 346 el.pause(); 347 }).catch(); 348 } 349 }); 350 } 351 352 Module.playerAutoPlay = function () { 353 const self = this; 354 const items = $('.is-autoplay'); 355 const nonResIframe = $('.entry-content > iframe'); 356 357 if (items != null && items.length > 0) { 358 items.each(function () { 359 const el = $(this); 360 if (!el.hasClass('is-loaded')) { 361 self.wPoint['iframe'] = new Waypoint({ 362 element: el, 363 handler: function () { 364 const iframe = el.find('iframe'); 365 self.initAutoPlay(iframe); 366 el.addClass('is-loaded'); 367 this.destroy(); 368 }, 369 offset: '60%' 370 }); 371 } 372 }) 373 } 374 375 if (nonResIframe != null && nonResIframe.length > 0) { 376 nonResIframe.each(function () { 377 const el = $(this); 378 if (!el.hasClass('is-loaded')) { 379 const iURL = el.attr('src'); 380 if (iURL.indexOf('youtube.com') > 0 || iURL.indexOf('youtu.be') > 0 || iURL.indexOf('vimeo.com') > 0) { 381 el.wrap('<div class="rb-ires is-loaded"></div>'); 382 } 383 } 384 }) 385 } 386 } 387 388 Module.initAutoPlay = function (item) { 389 if (item.length > 0 && undefined !== item[0]) { 390 const src = item[0].src; 391 if (src.indexOf('?') > -1) { 392 item[0].src += "&autoplay=1"; 393 } else { 394 item[0].src += "?autoplay=1"; 395 } 396 } 397 } 398 399 Module.tocToggle = function () { 400 this._document.on('click', '.toc-toggle', function (e) { 401 e.preventDefault(); 402 e.stopPropagation(); 403 404 const target = $(this); 405 const content = target.parents('.ruby-table-contents').find('.toc-content'); 406 content.toggle(200); 407 target.toggleClass('activate'); 408 }); 409 }; 410 411 /** Header JS functions */ 412 Module.headerDropdown = function () { 413 414 const self = this; 415 $('.more-trigger').on('click', function (e) { 416 417 e.preventDefault(); 418 e.stopPropagation(); 419 420 /** re calc menu */ 421 self.calcSubMenuPos(); 422 423 const target = $(this); 424 const holder = target.parents('.header-wrap').find('.more-section-outer'); 425 426 if (!holder.hasClass('dropdown-activated')) { 427 self._body.find('.dropdown-activated').removeClass('dropdown-activated'); 428 holder.addClass('dropdown-activated'); 429 } else { 430 holder.removeClass('dropdown-activated'); 431 } 432 if (target.hasClass('search-btn')) { 433 setTimeout(function () { 434 holder.find('input[type="text"]').focus() 435 }, 150); 436 } 437 438 return false; 439 }); 440 441 /** search trigger */ 442 $('.search-trigger').on('click', function (e) { 443 e.preventDefault(); 444 e.stopPropagation(); 445 const holder = $(this).parent('.header-dropdown-outer'); 446 if (!holder.hasClass('dropdown-activated')) { 447 self._body.find('.dropdown-activated').removeClass('dropdown-activated'); 448 holder.addClass('dropdown-activated'); 449 setTimeout(function () { 450 holder.find('input[type="text"]').focus() 451 }, 150); 452 } else { 453 holder.removeClass('dropdown-activated'); 454 } 455 return false; 456 }); 457 458 /** header dropdown */ 459 $('.dropdown-trigger').on('click', function (e) { 460 e.preventDefault(); 461 e.stopPropagation(); 462 const holder = $(this).parent('.header-dropdown-outer'); 463 if (!holder.hasClass('dropdown-activated')) { 464 self._body.find('.dropdown-activated').removeClass('dropdown-activated'); 465 holder.addClass('dropdown-activated'); 466 } else { 467 holder.removeClass('dropdown-activated'); 468 } 469 }); 470 } 471 472 Module.topSpacing = function () { 473 const self = this; 474 if (self._body.hasClass('top-spacing')) { 475 const height = $('.top-site-ad').outerHeight(); 476 $('.site-outer').css('margin-top', height); 477 } 478 } 479 480 /** outside click */ 481 Module.documentClick = function () { 482 483 const self = this; 484 const wrapper = $('.more-section-outer, .header-dropdown-outer, .mobile-collapse, .mfp-wrap'); 485 const inlineSearchForm = $('.is-form-layout'); 486 487 document.addEventListener('click', function (e) { 488 489 if (!wrapper.is(e.target) && wrapper.has(e.target).length === 0) { 490 wrapper.removeClass('dropdown-activated');
491 self.outerHTML.removeClass('collapse-activated'); 492 } 493 494 if (!inlineSearchForm.is(e.target) && inlineSearchForm.has(e.target).length === 0) { 495 inlineSearchForm.find('.live-search-response').fadeOut(500); 496 } 497 }); 498 } 499 500 /** calc mega menu position */ 501 Module.initSubMenuPos = function () { 502 const self = this; 503 let trigger = false; 504 505 /** add delay to ensure image loaded */ 506 setTimeout(function () { 507 self.calcSubMenuPos(); 508 }, 1000); 509 510 /** re calc when hovering */ 511 $('.menu-has-child-mega').on('mouseenter', function () { 512 if (!trigger) { 513 self.calcSubMenuPos(); 514 } 515 trigger = true; 516 }) 517 } 518 519 Module.calcSubMenuPos = function () { 520 521 if (window.outerWidth < 1025) { 522 return false; 523 } 524 525 const self = this; 526 const megaParents = $('.menu-has-child-mega'); 527 const headerWrapper = $('#site-header'); 528 529 /** for mega wide */ 530 if (megaParents.length > 0) { 531 megaParents.each(function () { 532 const item = $(this); 533 item.find('.mega-dropdown').css({ 534 'width': self._body.width(), 535 'left': -item.offset().left, 536 }); 537 item.addClass('mega-menu-loaded') 538 }) 539 } 540 541 /** sub-menu left right direction */ 542 if (headerWrapper.length > 0) { 543 544 let headerLeftOffset = headerWrapper.offset().left; 545 let headerWidth = headerWrapper.width(); 546 let headerRightOffset = headerLeftOffset + headerWidth; 547 548 const flexDropdown = $('.flex-dropdown'); 549 550 /** sub menu direction */ 551 const subElements = $('ul.sub-menu'); 552 if (subElements.length > 0) { 553 subElements.each(function () { 554 const item = $(this); 555 let itemLeftOffset = item.offset().left; 556 let itemRightOffset = itemLeftOffset + item.width() + 100; 557 if (itemRightOffset > headerRightOffset) { 558 item.addClass('left-direction'); 559 } 560 }) 561 } 562 563 /** calc dropdown flex width */ 564 if (flexDropdown.length > 0) { 565 flexDropdown.each(function () { 566 const item = $(this); 567 const parentItem = item.parent(); 568 if (parentItem.hasClass('is-child-wide') || item.hasClass('mega-has-left')) { 569 return; 570 } 571 const itemWidth = item.width(); 572 const itemHalfWidth = itemWidth / 2; 573 const parentItemOffset = parentItem.offset().left; 574 const parentHalfWidth = parentItem.width() / 2; 575 const parentItemCenterOffset = parentItemOffset + parentHalfWidth; 576 const rightSpacing = headerRightOffset - parentItemCenterOffset; 577 const leftSpacing = parentItemCenterOffset - headerLeftOffset; 578 579 if (itemWidth >= headerWidth) { 580 item.css({ 581 'width': headerWidth - 2, 582 'left': -parentItemOffset 583 }); 584 } else if (itemHalfWidth > rightSpacing) { 585 item.css({ 586 'right': -rightSpacing + parentHalfWidth + 1, 587 'left': 'auto', 588 }); 589 } else if (itemHalfWidth > leftSpacing) { 590 item.css({ 591 'left': -leftSpacing + parentHalfWidth + 1, 592 'right': 'auto', 593 }); 594 } else { 595 item.css({ 596 'right': 'auto', 597 'left': -itemHalfWidth + parentHalfWidth, 598 }); 599 } 600 }); 601 } 602 } 603 } 604 605 /** 606 * 607 * @returns {boolean} 608 */ 609 Module.stickyNavBar = function () { 610 611 const self = this; 612 613 /** turn off sticky on editor mode */ 614 if (self._body.hasClass('elementor-editor-active')) { 615 return false; 616 } 617 618 self.sticky.section = $('#sticky-holder'); 619 self.sticky.outer = $('#navbar-outer'); 620 621 if ((!self._body.hasClass('is-mstick') && !self._body.hasClass('yes-tstick')) || self.sticky.outer.length < 1 || self.sticky.section.length < 1) { 622 return false; 623 } 624
625 self.sticky.smartSticky = !!self._body.hasClass('is-smart-sticky'); 626 self.sticky.isSticky = false; 627 self.sticky.lastScroll = 0; 628 629 if (self._body.hasClass('yes-tstick')) { 630 self.sticky.isTitleSticky = true; 631 } else { 632 self.sticky.isTitleSticky = 0; 633 } 634 635 self.sticky.additionalOffset = 200; 636 if (window.innerWidth > 1024) { 637 if (self.sticky.isTitleSticky) { 638 self.sticky.additionalOffset = 450; 639 } else { 640 self.sticky.additionalOffset = 0; 641 } 642 } 643 644 if (self._body.hasClass('admin-bar')) { 645 self.sticky.adminBarSpacing = 32; 646 } else { 647 self.sticky.adminBarSpacing = 0; 648 } 649 650 self.sticky.topOffset = self.sticky.section.offset().top; 651 self.sticky.stickySectionHeight = self.sticky.section.outerHeight(); 652 653 self.sticky.outer.css('min-height', self.sticky.outer.outerHeight()); 654 self.sticky.activatePos = self.sticky.topOffset + 1 + self.sticky.stickySectionHeight + self.sticky.additionalOffset; 655 self.sticky.deactivePos = self.sticky.topOffset - self.sticky.adminBarSpacing + self.sticky.additionalOffset; 656 657 if (window.addEventListener) { 658 if (self.sticky.smartSticky) { 659 window.addEventListener('scroll', function () { 660 self.animationFrame(self.initSmartStickyNavBar.bind(self)); 661 }, false); 662 } else { 663 window.addEventListener('scroll', function () { 664 self.animationFrame(self.initStickyNavBar.bind(self)); 665 }, false); 666 } 667 } 668 669 self._window.on('unstickMenu', function () { 670 self.sticky.outer.css('min-height', self.sticky.outer.outerHeight()); 671 self.sticky.stickySectionHeight = self.sticky.section.outerHeight(); 672 self.sticky.topOffset = self.sticky.section.offset().top; 673 self.sticky.activatePos = self.sticky.topOffset + 1 + self.sticky.stickySectionHeight + self.sticky.additionalOffset; 674 self.sticky.deactivePos = self.sticky.topOffset - self.sticky.adminBarSpacing + self.sticky.additionalOffset; 675 }); 676 } 677 678 Module.initStickyNavBar = function () { 679 const self = this; 680 const scroll = self._window.scrollTop(); 681 682 if (!self.sticky.isSticky && scroll > self.sticky.activatePos) { 683 self.sticky.isSticky = true; 684 self._body.addClass('stick-animated sticky-on'); 685 self.sticky.stickAnimatedTimeout = setTimeout(function () { 686 self._body.removeClass('stick-animated'); 687 }, 200); 688 } else if (self.sticky.isSticky && scroll <= self.sticky.deactivePos) { 689 self.sticky.isSticky = false; 690 self._body.removeClass('sticky-on stick-animated'); 691 self._window.trigger('unstickMenu'); 692 } 693 } 694 695 Module.initSmartStickyNavBar = function () { 696 const self = this; 697 const scroll = self._window.scrollTop(); 698 699 if (!self.sticky.isSticky && scroll > self.sticky.activatePos && scroll < self.sticky.lastScroll) { 700 self.sticky.isSticky = true; 701 self._body.addClass('stick-animated sticky-on'); 702 self.sticky.stickAnimatedTimeout = setTimeout(function () { 703 self._body.removeClass('stick-animated'); 704 }, 200); 705 } else if (self.sticky.isSticky && (scroll <= self.sticky.deactivePos || scroll > self.sticky.lastScroll)) { 706 self.sticky.isSticky = false; 707 self._body.removeClass('sticky-on stick-animated'); 708 if (scroll <= self.sticky.deactivePos) { 709 self._window.trigger('unstickESection'); 710 } 711 } 712 self.sticky.lastScroll = scroll; 713 } 714 715 /** header sticky template */ 716 Module.stickyHeaderBuilder = function () { 717 718 const self = this; 719 720 /** turn off sticky on editor mode */ 721 if (self._body.hasClass('elementor-editor-active')) { 722 return false; 723 } 724 725 let stickySection = $('.header-template .e-section-sticky').first(); 726 const hasTitleSticky = $('body.single-post #s-title-sticky').first(); 727 728 if (stickySection.length < 1) { 729 return false; 730 } 731 732 if (hasTitleSticky.length > 0) { 733 self._body.addClass('yes-tstick'); 734 self.eSticky.isTitleSticky = true; 735 } else { 736 self.eSticky.isTitleSticky = 0; 737 } 738 739 self.eSticky.additionalOffset = 200; 740 if (window.innerWidth > 1024) { 741 if (self.eSticky.isTitleSticky) { 742 self.eSticky.additionalOffset = 450; 743 } else { 744 self.eSticky.additionalOffset = 0; 745 } 746 } 747
748 self.eSticky.smartSticky = !!stickySection.hasClass('is-smart-sticky'); 749 750 /** mobile sticky for header template */ 751 if (window.innerWidth <= 1024) { 752 stickySection.removeClass('e-section-sticky'); 753 stickySection = $('#header-template-holder').addClass('e-section-sticky'); 754 } 755 756 self.eSticky.section = stickySection; 757 self.eSticky.outer = stickySection.parent(); 758 759 self.eSticky.adminBarSpacing = 0; 760 self.eSticky.isSticky = false; 761 self.eSticky.lastScroll = 0; 762 self.eSticky.stickySectionHeight = stickySection.outerHeight(); 763 self.eSticky.topOffset = stickySection.offset().top; 764 765 /** set min height */ 766 if (self._body.hasClass('admin-bar')) { 767 self.eSticky.adminBarSpacing = 32; 768 } 769 self.eSticky.outer.css('min-height', self.eSticky.outer.outerHeight()); 770 self.eSticky.activatePos = self.eSticky.topOffset + 1 + self.eSticky.stickySectionHeight + self.eSticky.additionalOffset; 771 self.eSticky.deactivePos = self.eSticky.topOffset - self.eSticky.adminBarSpacing + self.eSticky.additionalOffset; 772 773 if (window.addEventListener) { 774 if (self.eSticky.smartSticky) { 775 window.addEventListener('scroll', function () { 776 self.animationFrame(self.initSmartStickyESection.bind(self)); 777 }, false); 778 } else { 779 window.addEventListener('scroll', function () { 780 self.animationFrame(self.initStickyESection.bind(self)); 781 }, false); 782 } 783 } 784 785 /** re-calc height values */ 786 self._window.on('unstickESection', function () { 787 self.eSticky.outer.css('min-height', self.eSticky.outer.outerHeight()); 788 self.eSticky.stickySectionHeight = self.eSticky.section.outerHeight(); 789 self.eSticky.topOffset = self.eSticky.section.offset().top; 790 self.eSticky.activatePos = self.eSticky.topOffset + 1 + self.eSticky.stickySectionHeight + self.eSticky.additionalOffset; 791 self.eSticky.deactivePos = self.eSticky.topOffset - self.eSticky.adminBarSpacing + self.eSticky.additionalOffset; 792 }); 793 } 794 795 Module.initStickyESection = function () { 796 const self = this; 797 const scroll = self._window.scrollTop(); 798 if (!self.eSticky.isSticky && scroll > self.eSticky.activatePos) { 799 self.eSticky.isSticky = true; 800 self._body.addClass('stick-animated sticky-on'); 801 self.eSticky.stickAnimatedTimeout = setTimeout(function () { 802 self._body.removeClass('stick-animated'); 803 }, 200); 804 } else if (self.eSticky.isSticky && scroll <= self.eSticky.deactivePos) { 805 self.eSticky.isSticky = false; 806 self._body.removeClass('sticky-on stick-animated'); 807 self._window.trigger('unstickESection'); 808 } 809 } 810 811 Module.initSmartStickyESection = function () { 812 const self = this; 813 const scroll = self._window.scrollTop(); 814 815 if (!self.eSticky.isSticky && scroll > self.eSticky.activatePos && scroll < self.eSticky.lastScroll) { 816 self.eSticky.isSticky = true; 817 self._body.addClass('stick-animated sticky-on'); 818 self.eSticky.stickAnimatedTimeout = setTimeout(function () { 819 self._body.removeClass('stick-animated'); 820 }, 200); 821 } else if (self.eSticky.isSticky && (scroll <= self.eSticky.deactivePos || scroll > self.eSticky.lastScroll)) { 822 self.eSticky.isSticky = false; 823 self._body.removeClass('sticky-on stick-animated'); 824 if (scroll <= self.eSticky.deactivePos) { 825 self._window.trigger('unstickESection'); 826 } 827 } 828 829 self.eSticky.lastScroll = scroll; 830 } 831 832 /** mobileCollapse */ 833 Module.mobileCollapse = function () { 834 const self = this; 835 const $mobileMenuTrigger = $('.mobile-menu-trigger'); 836 const $outerHTML = self.outerHTML; 837 const $mobileSearchForm = $outerHTML.find('.mobile-search-form input[type="text"]'); 838 839 $mobileMenuTrigger.on('click', function (e) { 840 e.preventDefault(); 841 e.stopPropagation(); 842 const target = $(this); 843 844 if (target.hasClass('mobile-search-icon')) { 845 setTimeout(function () { 846 $mobileSearchForm.focus(); 847 }, 100); 848 } 849 850 const isCollapseActivated = $outerHTML.hasClass('collapse-
850activated'); 851 $outerHTML.toggleClass('collapse-activated', !isCollapseActivated); 852 }); 853 } 854 855 /** 856 * privacy trigger 857 */ 858 Module.privacyTrigger = function () { 859 const self = this; 860 $('#privacy-trigger').on('click', function (e) { 861 e.preventDefault(); 862 e.stopPropagation(); 863 self.setStorage('RubyPrivacyAllowed', '1'); 864 $('#rb-privacy').slideUp(200, function () { 865 $(this).remove(); 866 }); 867 return false; 868 }); 869 } 870 871 /** back top */ 872 Module.backTop = function () { 873 if (this._body.hasClass('is-backtop')) { 874 $().UItoTop({ 875 text: '<i class="rbi rbi-darrow-top"></i>', 876 }); 877 } 878 } 879 880 /** login popup */ 881 Module.loginPopup = function () { 882 883 const self = this; 884 const form = $('#rb-user-popup-form'); 885 if (form.length < 1) { 886 return false; 887 } 888 this._document.on('click', '.login-toggle', (e) => { 889 e.preventDefault(); 890 e.stopPropagation(); 891 $.magnificPopup.open({ 892 type: 'inline', 893 preloader: false, 894 removalDelay: 400, 895 showCloseBtn: true, 896 closeBtnInside: true, 897 closeOnBgClick: false, 898 items: { 899 src: form, 900 type: 'inline' 901 }, 902 mainClass: 'rb-popup-center', 903 closeMarkup: '<span class="close-popup-btn mfp-close"><span class="close-icon"></span></span>', 904 fixedBgPos: true, 905 fixedContentPos: true, 906 callbacks: {open: () => self.reloadCaptchaPopups()} 907 }); 908 }); 909 }; 910 911 /** popup template blocks */ 912 Module.popupTemplate = function () { 913 914 const templateCache = {}; 915 this._document.on('click', '.popup-trigger-btn', (e) => { 916 917 e.preventDefault(); 918 e.stopPropagation(); 919 920 const target = $(e.target); 921 const templateID = target.data('trigger') || ''; 922 const position = target.data('position') || ''; 923 924 if (!templateCache[templateID]) { 925 const template = $(`#tmpl-${templateID}`); 926 if (template.length === 0) { 927 return; 928 } 929 templateCache[templateID] = template.html(); 930 } 931 $.magnificPopup.open({ 932 type: 'inline', 933 preloader: false, 934 removalDelay: 400, 935 showCloseBtn: true, 936 closeBtnInside: true, 937 closeOnBgClick: true, 938 allowHTMLInTemplate: true, 939 items: { 940 src: templateCache[templateID], 941 type: 'inline' 942 }, 943 mainClass: `is-template-popup popup-${templateID} ${position}`, 944 closeMarkup: '<span class="close-popup-btn mfp-close"><span class="close-icon"></span></span>', 945 fixedBgPos: true, 946 fixedContentPos: true, 947 callbacks: {open: () => self.reloadCaptchaPopups()}, 948 }); 949 }); 950 }; 951 952 /** newsletter */ 953 Module.popupNewsletter = function () { 954 955 const self = this; 956 if (self.popupNewsletterEl.length > 0) { 957 const display = self.popupNewsletterEl.data('display'); 958 self.newsletterExpired = self.popupNewsletterEl.data('expired'); 959 self.newsletterDisplayOffset = self.popupNewsletterEl.data('offset');
960 const delay = self.popupNewsletterEl.data('delay'); 961 const oldExpired = self.getStorage('RubyNewsletterExpired'); 962 963 if (self.newsletterExpired === 0) { 964 self.deleteStorage('RubyNewsletter'); 965 } 966 967 if (!oldExpired || self.newsletterExpired !== oldExpired) { 968 self.setStorage('RubyNewsletterExpired', self.newsletterExpired); 969 self.deleteStorage('RubyNewsletter'); 970 } 971 972 if (!self.getTTLStorage('RubyNewsletter')) { 973 if (!display || 'scroll' === display) { 974 if (window.addEventListener) { 975 window.addEventListener('scroll', function () { 976 self.animationFrame(self.scrollPopupNewsletter.bind(self)); 977 }, false); 978 } 979 } else { 980 setTimeout(function () { 981 self.popupNewsletterInit(); 982 }, delay); 983 } 984 } 985 } 986 } 987 988 Module.scrollPopupNewsletter = function () { 989 const self = this; 990 if (!self.newsletterPopupFlag && self._window.scrollTop() > self.newsletterDisplayOffset) { 991 self.newsletterPopupFlag = true; 992 self.popupNewsletterInit(); 993 } 994 } 995 996 Module.popupNewsletterInit = function () { 997 998 const self = this; 999 if (self.siteAccessFlag) { 1000 return; 1001 } 1002 1003 if (!self.popupNewsletterEl.hasClass('is-pos-fixed')) { 1004 $.magnificPopup.open({ 1005 type: 'inline', 1006 preloader: false, 1007 closeBtnInside: true, 1008 removalDelay: 400, 1009 showCloseBtn: true, 1010 closeOnBgClick: false, 1011 disableOn: 1024, 1012 items: { 1013 src: '#rb-popup-newsletter', 1014 type: 'inline' 1015 }, 1016 mainClass: 'rb-popup-center', 1017 fixedBgPos: true, 1018 fixedContentPos: true, 1019 closeMarkup: '<span class="close-popup-btn mfp-close"><span class="close-icon"></span></span>', 1020 callbacks: { 1021 open: () => self.reloadCaptchaPopups(), 1022 close: function () { 1023 if (self.siteAccessFlag) { 1024 return; 1025 } 1026 self.SetTTLStorage('RubyNewsletter', 1, self.newsletterExpired * 24); 1027 } 1028 } 1029 }); 1030 } else { 1031 self.popupNewsletterEl.removeClass('is-hidden'); 1032 setTimeout(() => { 1033 self.popupNewsletterEl.addClass('yes-show'); 1034 }, 10); 1035 const closeBtn = self.popupNewsletterEl.find('.close-popup-btn'); 1036 closeBtn.on('click', function () { 1037 self.SetTTLStorage('RubyNewsletter', 1, self.newsletterExpired * 24); 1038 self.popupNewsletterEl.removeClass('yes-show'); 1039 setTimeout(() => { 1040 self.popupNewsletterEl.addClass('is-hidden'); 1041 }, 400); 1042 }); 1043 } 1044 } 1045 1046 /** footer slide up */ 1047 Module.footerSlideUp = function () { 1048 const target = $('#footer-slideup'); 1049 if (target.length > 0) { 1050 const self = this; 1051 self.footerSlideUpExpired = target.data('expired'); 1052 const delay = target.data('delay'); 1053 const oldExpired = self.getStorage('footerSlideUpExpired'); 1054 if (!oldExpired || self.footerSlideUpExpired != oldExpired) { 1055 self.setStorage('footerSlideUpExpired', self.footerSlideUpExpired); 1056 self.deleteStorage('footerSlideUp'); 1057 } 1058 if (!self.getTTLStorage('footerSlideUp')) { 1059 setTimeout(function () { 1060 self.footerSlideUpInit(); 1061 }, delay); 1062 } 1063 /** show hide toggle */ 1064 setTimeout(function () { 1065 self.footerSlideUpToggle(); 1066 }, delay); 1067 } 1068 } 1069 1070 Module.footerSlideUpToggle = function () { 1071 const self = this; 1072 $('.slideup-toggle').off('click').on('click', function (e) { 1073 e.preventDefault(); 1074 e.stopPropagation(); 1075 self.footerSlideUpInit(); 1076 return false; 1077 }); 1078 } 1079 1080 Module.footerSlideUpInit = function () { 1081 if (this._body.hasClass('yes-f-slideup')) { 1082 this._body.removeClass('yes-f-slideup'); 1083 this.SetTTLStorage('footerSlideUp', 1, this.footerSlideUpExpired * 24); 1084 } else { 1085 this._body.addClass('yes-f-slideup'); 1086 this.deleteStorage('footerSlideUp'); 1087 } 1088 } 1089 1090 /** youtube iframe */ 1091 Module.loadYoutubeIframe = function () { 1092 1093 const self = this; 1094 const blockPlaylist = $('.yt-playlist'); 1095 if (blockPlaylist.length > 0) { 1096 const tag = document.createElement('script'); 1097 tag.src = "//www.youtube.com/iframe_api"; 1098 const firstScriptTag = document.getElementsByTagName('script')[0]; 1099 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 1100 } 1101 1102 window.onYouTubeIframeAPIReady = function () { 1103 $('.yt-playlist').each(function () { 1104 const target = $(this); 1105 const iframe = target.find('.yt-player'); 1106 const videoID = target.data('id'); 1107 const blockID = target.data('block'); 1108 self.YTPlayers[blockID] = new YT.Player(iframe.get(0), { 1109 height: '540', 1110 width: '960', 1111 videoId: videoID, 1112 events: { 1113 'onReady': self.videoPlayToggle, 1114 'onStateChange': self.videoPlayToggle 1115 } 1116 }); 1117 }); 1118 1119 $('.plist-item').on('click', function (e) { 1120 e.preventDefault(); 1121 e.stopPropagation(); 1122 1123 const target = $(this); 1124 const wrapper = target.closest('.yt-playlist'); 1125 const currentBlockID = wrapper.data('block'); 1126 const videoID = target.data('id'); 1127 const title = target.find('.plist-item-title').text(); 1128 const meta = target.data('index'); 1129
1130 Object.keys(self.YTPlayers).forEach(function (id) { 1131 self.YTPlayers[id].pauseVideo(); 1132 }); 1133 self.YTPlayers[currentBlockID].loadVideoById({ 1134 'videoId': videoID 1135 }); 1136 1137 wrapper.find('.yt-trigger').addClass('is-playing'); 1138 wrapper.find('.play-title').hide().text(title).fadeIn(200); 1139 wrapper.find('.video-index').text(meta); 1140 }); 1141 } 1142 } 1143 1144 Module.videoPlayToggle = function () { 1145 1146 const players = FOXIZ_MAIN_SCRIPT.YTPlayers; 1147 1148 $('.yt-trigger').on('click', function (e) { 1149 e.preventDefault(); 1150 e.stopPropagation(); 1151 1152 const target = $(this); 1153 const currentBlockID = target.closest('.yt-playlist').data('block'); 1154 const currentState = players[currentBlockID].getPlayerState(); 1155 const isPlaying = [1, 3].includes(currentState); 1156 if (!isPlaying) { 1157 players[currentBlockID].playVideo(); 1158 target.addClass('is-playing'); 1159 } else { 1160 players[currentBlockID].pauseVideo(); 1161 target.removeClass('is-playing'); 1162 } 1163 }); 1164 } 1165 1166 /** Comment scripts */ 1167 Module.showPostComment = function () { 1168 const self = this; 1169 1170 this._document.on('click', '.smeta-sec .meta-comment', function (e) { 1171 e.stopPropagation(); 1172 const commentBtn = $('.show-post-comment'); 1173 if (commentBtn.length > 0) { 1174 self.html.animate({scrollTop: commentBtn.offset().top}, 300); 1175 commentBtn.trigger('click'); 1176 } 1177 }); 1178 1179 this._document.on('click', '.show-post-comment', function (e) { 1180 e.preventDefault(); 1181 e.stopPropagation(); 1182 const target = $(this); 1183 const wrap = target.parent(); 1184 1185 target.fadeOut(200, function () { 1186 target.remove(); 1187 wrap.find('.is-invisible').removeClass('is-invisible'); 1188 wrap.next('.comment-holder').removeClass('is-hidden'); 1189 }) 1190 }); 1191 } 1192 1193 /** table scroll */ 1194 Module.scrollTableContent = function () { 1195 1196 const self = this; 1197 const behavior = self._body.hasClass('toc-smooth') ? 'smooth' : 'instant'; 1198 1199 self._document.on('click', '.anchor-link', function (e) { 1200 e.stopPropagation(); 1201 1202 const targetClass = $(this).data('index'); 1203 if (!targetClass) return; 1204 1205 let $scrollElement = $(`.${targetClass}`); 1206 1207 // if target not found, search inside its parent .s-ct 1208 if (!$scrollElement.length) { 1209 const $parentContainer = $(this).closest('.s-ct'); 1210 if ($parentContainer.length) { 1211 $scrollElement = $parentContainer.find('.restrict-box, .continue-reading-btn').first(); 1212 } 1213 } 1214 1215 if (!$scrollElement.length) return; 1216 1217 setTimeout(() => { 1218 window.scrollTo({ 1219 top: $scrollElement.offset().top, 1220 behavior: behavior, 1221 }); 1222 }, 10); 1223 }); 1224 }; 1225 1226 /** scroll to comment */ 1227 Module.scrollToComment = function () { 1228 const self = this; 1229 const hash = window.location.hash; 1230 if (hash === '#respond' || hash.startsWith('#comment')) { 1231 const commentBtn = $('.show-post-comment').first(); 1232 if (commentBtn.length === 0) { 1233 return; 1234 } 1235 self.html.animate({scrollTop: commentBtn.offset().top - 200}, 400); 1236 commentBtn.trigger('click'); 1237 } 1238 } 1239 1240 Module.replyReview = function () { 1241 this._document.on('click', '.comment-reply-link', function () { 1242 const target = $(this); 1243 const wrapper = target.parents('.rb-reviews-area'); 1244 const cancelLink = $('#cancel-comment-reply-link'); 1245 if (wrapper.length > 0) { 1246 wrapper.find('.rb-form-rating').addClass('is-hidden'); 1247 cancelLink.on('click', function () { 1248 wrapper.find('.rb-form-rating').removeClass('is-hidden'); 1249 }); 1250 } 1251 }); 1252 } 1253 1254 /** user rating */ 1255 Module.usersRating = function () { 1256 const self = this; 1257 const reviewsForm = self._body.find('.rb-reviews-form'); 1258 if (reviewsForm.length > 0) { 1259 reviewsForm.each(function () { 1260 const reviewForm = $(this); 1261 if (!reviewForm.hasClass('is-loaded')) { 1262 reviewForm.addClass('is-loaded'); 1263 const ratingForm = reviewForm.find('.rb-form-rating'); 1264 const selection = reviewForm.find('.rb-rating-selection'); 1265 const text = reviewForm.find('.rating-alert').html();
1266 let ratingValue = null; 1267 1268 selection.val(''); 1269 selection.hide(); 1270 selection.before( 1271 '<div class="rb-review-stars">\ 1272 <span>\ 1273 <a class="star" data-rating="1" href="#"><i class="rbi rbi-star-o"></i></a>\ 1274 <a class="star" data-rating="2" href="#"><i class="rbi rbi-star-o"></i></a>\ 1275 <a class="star" data-rating="3" href="#"><i class="rbi rbi-star-o"></i></a>\ 1276 <a class="star" data-rating="4" href="#"><i class="rbi rbi-star-o"></i></a>\ 1277 <a class="star" data-rating="5" href="#"><i class="rbi rbi-star-o"></i></a>\ 1278 </span>\ 1279 </div>' 1280 ); 1281 1282 ratingForm.on('click', 'a.star', function (e) { 1283 e.preventDefault(); 1284 e.stopPropagation(); 1285 const star = $(this); 1286 ratingValue = star.data('rating'); 1287 star.siblings('a').removeClass('active'); 1288 star.addClass('active'); 1289 ratingForm.addClass('selected'); 1290 }); 1291 1292 reviewForm.on('click', '#respond #submit', function () { 1293 selection.val(ratingValue); 1294 if (!selection.val()) { 1295 window.alert(text); 1296 return false; 1297 } 1298 }); 1299 } 1300 }); 1301 } 1302 } 1303 1304 /** 1305 * 1306 * @returns {boolean} 1307 */ 1308 Module.readIndicatorInit = function () { 1309 1310 const self = this; 1311 if (!self._body.hasClass('single') || self.readIndicator.length < 1) { 1312 return false; 1313 } 1314 1315 let content = $('.entry-content').first(); 1316 if (!content.length) return false; 1317 1318 self.indicatorTop = content.offset().top; 1319 self.indicatorHeight = content.outerHeight(true) - self._window.height(); 1320 /** delay for load images */ 1321 setTimeout(function () { 1322 self.indicatorTop = content.offset().top; 1323 self.indicatorHeight = content.outerHeight(true) - self._window.height(); 1324 }, 1000) 1325 1326 if (window.addEventListener) { 1327 window.addEventListener('scroll', function () { 1328 self.animationFrame(self.readIndicatorCalc.bind(self)); 1329 }, false); 1330 } 1331 } 1332 1333 Module.readIndicatorCalc = function () { 1334 const self = this; 1335 const scroll = self._window.scrollTop(); 1336 self.readIndicatorPercent = Math.min(((scroll - self.indicatorTop) / self.indicatorHeight) * 100, 100); 1337 if (self.readIndicatorPercent <= 100) { 1338 self.readIndicator.css('width', self.readIndicatorPercent + '%'); 1339 } 1340 } 1341 1342 /** breaking news */ 1343 Module.breakingNews = function () { 1344 const self = this; 1345 const breakingNews = $('.breaking-news-slider') 1346 1347 if (breakingNews.length < 1) { 1348 return false; 1349 } 1350 1351 breakingNews.each(function () { 1352 const el = $(this); 1353 let params = { 1354 slidesPerView: 1, 1355 loop: true, 1356 } 1357 if (el.data('play')) { 1358 params.autoplay = { 1359 delay: el.data('speed') || self.themeSettings.sliderSpeed, 1360 stopOnLastSlide: false, 1361 disableOnInteraction: self.isElementorEditor ? true : (window.outerWidth < 1025), 1362 pauseOnMouseEnter: true 1363 }; 1364 } 1365 params.navigation = { 1366 nextEl: el.find('.breaking-news-next')[0], 1367 prevEl: el.find('.breaking-news-prev')[0] 1368 } 1369 new RBSwiper(this, params); 1370 }); 1371 } 1372 1373 /** overlay slider */ 1374 Module.sliders = function () { 1375 1376 const self = this; 1377 const sliders = $('.post-slider'); 1378 if (sliders.length < 1) { 1379 return false; 1380 } 1381 1382 sliders.each(function () { 1383 const slider = $(this); 1384 let params = { 1385 grabCursor: true, 1386 allowTouchMove: true, 1387 effect: self.themeSettings.sliderEffect, 1388 loop: true, 1389 } 1390 if (slider.data('play')) { 1391 params.autoplay = { 1392 delay: slider.data('speed') || self.themeSettings.sliderSpeed, 1393 stopOnLastSlide: true, 1394 disableOnInteraction: self.isElementorEditor ? true : (window.outerWidth < 1025), 1395 pauseOnMouseEnter: true 1396 }; 1397 } 1398 1399 params.pagination = { 1400 el: slider.find('.slider-pagination')[0], 1401 clickable: true, 1402 }; 1403 1404 params.navigation = { 1405 nextEl: slider.find('.slider-next')[0], 1406 prevEl: slider.find('.slider-prev')[0] 1407 } 1408 new RBSwiper(this, params); 1409 }); 1410 } 1411 1412 /** carousel blocks */ 1413 Module.carousels = function () { 1414 const self = this; 1415 const carousels = $('.post-carousel'); 1416 if (carousels.length < 1) { 1417 return false; 1418 } 1419 carousels.each(function () { 1420 const carousel = $(this); 1421 let params = { 1422 grabCursor: true, 1423 allowTouchMove: true, 1424 freeMode: false, 1425 loop: true 1426 } 1427 params.slidesPerView = carousel.data('mcol'); 1428 params.spaceBetween = carousel.data('mgap'); 1429 params.centeredSlides = carousel.data('centered'); 1430 1431 params.navigation = { 1432 nextEl: carousel.find('.slider-next')[0], 1433 prevEl: carousel.find('.slider-prev')[0] 1434 } 1435 if (carousel.find('.slider-pagination')[0]) { 1436 params.pagination = { 1437 el: carousel.find('.slider-pagination')[0], 1438 type: 'bullets', 1439 clickable: true, 1440 }; 1441 } 1442 1443 if (carousel.data('play')) { 1444 params.autoplay = { 1445 delay: carousel.data('speed') || self.themeSettings.sliderSpeed, 1446 stopOnLastSlide: false, 1447 disableOnInteraction: self.isElementorEditor ? true : (window.outerWidth < 1025), 1448 pauseOnMouseEnter: true 1449 }; 1450 } 1451 1452 if (carousel.data('fmode')) { 1453 params.freeMode = true; 1454 } 1455 params.breakpoints = { 1456 768: { 1457 slidesPerView: carousel.data('tcol'), 1458 spaceBetween: carousel.data('tgap') 1459 }, 1460 1025: { 1461 slidesPerView: carousel.data('col'), 1462 spaceBetween: carousel.data('gap') 1463 }, 1464 1500: { 1465 slidesPerView: carousel.data('wcol'), 1466 spaceBetween: carousel.data('gap') 1467 } 1468 }; 1469 params.on = { 1470 afterInit: function (swiper) { 1471 const wrap = $(swiper.$wrapperEl); 1472 $(swiper.$wrapperEl).find('.p-box').css('height', wrap.height()); 1473 }, 1474 resize: function (swiper) { 1475 const wrap = $(swiper.$wrapperEl); 1476 $(swiper.$wrapperEl).find('.p-box').css('height', wrap.height()); 1477 }, 1478 }; 1479 1480 new RBSwiper(this, params); 1481 }); 1482 } 1483 1484 /* ================================ SINGLE GALLERY ================================ */ 1485 Module.singleGallery = function () { 1486 1487 const self = this; 1488 const gallerySections = self._body.find('.featured-gallery-wrap'); 1489 if (gallerySections.length === 0) { 1490 return; 1491 } 1492 1493 gallerySections.each(function () { 1494 const section = $(this); 1495 if (!section.hasClass('is-loaded')) { 1496 const index = section.data('gallery'); 1497 const sliderEl = section.find('.gallery-slider').attr('id'); 1498 const sliderNavEl = section.find('.gallery-slider-nav').attr('id'); 1499 const carouselEl = section.find('.gallery-carousel').attr('id'); 1500 const coverflowEL = section.find('.gallery-coverflow').attr('id'); 1501 1502 if (sliderEl && sliderNavEl) { 1503 1504 const navEl = $('#' + sliderNavEl); 1505 const navSlidesCount = navEl.find('.swiper-slide').length; 1506 const shouldLoopNav = navSlidesCount >= 6; 1507 const viewSlides = Math.min(navSlidesCount, 6); 1508 1509 if (!shouldLoopNav) { 1510 navEl.css('max-width', `${navSlidesCount * 125}px`); 1511 } 1512 1513 const galleryNav = new RBSwiper('#' + sliderNavEl, { 1514 spaceBetween: 15, 1515 slidesPerView: viewSlides, 1516 freeMode: self.themeSettings.sliderFMode, 1517 grabCursor: true, 1518 loop: shouldLoopNav, 1519 watchSlidesVisibility: shouldLoopNav, 1520 watchSlidesProgress: true, 1521 on: { 1522 init: function () { 1523 $(this.$wrapperEl).removeClass('pre-load'); 1524 }, 1525 }, 1526 }); 1527 1528 const gallerySlider = new RBSwiper('#' + sliderEl, { 1529 spaceBetween: 0, 1530 grabCursor: true, 1531 loop: true, 1532 pagination: { 1533 el: '.swiper-pagination-' + index, 1534 type: 'progressbar', 1535 clickable: true, 1536 }, 1537 on: { 1538 init: function () { 1539 section.addClass('is-loaded'); 1540 }, 1541 }, 1542 thumbs: { 1543 swiper: galleryNav 1544 } 1545 }); 1546 1547 gallerySlider.on('slideChange', function () { 1548 const index = this.activeIndex; 1549 if (index) { 1550 const label = $(this.$el).next().find('.current-slider-count'); 1551 label.fadeOut(0, function () { 1552 $(this).html(index <= label.data('total') ? index : 1).fadeIn(50); 1553 }); 1554 } 1555 }); 1556 } 1557 1558 if ('undefined' !== typeof carouselEl) { 1559 new RBSwiper('#' + carouselEl, { 1560 spaceBetween: 20, 1561 slidesPerView: 'auto', 1562 freeMode: self.themeSettings.sliderFMode, 1563 loop: false, 1564 grabCursor: true, 1565 scrollbar: { 1566 el: '.swiper-scrollbar-' + index, 1567 hide: true, 1568 }, 1569 on: { 1570 init: function () { 1571 $(this.$wrapperEl).removeClass('pre-load'); 1572 section.addClass('is-loaded'); 1573 }, 1574 }, 1575 }); 1576 } 1577 1578 if ('undefined' !== typeof coverflowEL) { 1579 new RBSwiper('#' + coverflowEL, { 1580 effect: "coverflow", 1581 grabCursor: true, 1582 centeredSlides: true, 1583 slidesPerView: 1.2, 1584 coverflowEffect: { 1585 rotate: 50, 1586 stretch: 0, 1587 depth: 250, 1588 modifier: 1, 1589 slideShadows: true, 1590 }, 1591 breakpoints: { 1592 768: { 1593 slidesPerView: 3 1594 } 1595 }, 1596 on: { 1597 init: function () { 1598 $(this.$wrapperEl).removeClass('pre-load'); 1599 section.addClass('is-loaded'); 1600 }, 1601 }, 1602 pagination: { 1603 el: '.swiper-pagination-' + index, 1604 clickable: true, 1605 }, 1606 }); 1607 } 1608 } 1609 }); 1610 } 1611 1612 Module.scrollBarSlider = function () { 1613 1614 const self = this; 1615 const items = $('.gb-slider-scrollbar'); 1616 if (!items.length) return; 1617 1618 items.each(function (index, itemEl) { 1619 if ($(itemEl).hasClass('is-loaded')) return; 1620 1621 const autoplay = $(itemEl).data('autoplay') === 1; 1622 const caption = $(itemEl).closest('.gb-image-slider').find('.gb-image-caption'); 1623 const scrollbarEl = $(itemEl).find('.swiper-scrollbar')[0]; 1624 1625 $(itemEl).find('.swiper-wrapper').children().addClass('swiper-slide'); 1626 1627 const updateCaption = (swiper) => { 1628 const captionText = $(swiper.slides[swiper.activeIndex]).find('.wp-element-caption').html() || ''; 1629 caption.fadeOut(150, () => caption.html(captionText).fadeIn(200)); 1630 }; 1631 1632 new RBSwiper(itemEl, { 1633 slidesPerView: 1, 1634 loop: false, 1635 grabCursor: true, 1636 autoplay: autoplay ? { 1637 delay: self.themeSettings.sliderSpeed || 5000, 1638 disableOnInteraction: self.isElementorEditor ? true : window.outerWidth < 1025, 1639 } : false, 1640 scrollbar: { 1641 el: scrollbarEl, 1642 hide: false, 1643 }, 1644 on: { 1645 init() { 1646 $(itemEl).removeClass('pre-load').addClass('is-loaded'); 1647 updateCaption(this); 1648 }, 1649 sl
1649ideChange() { 1650 updateCaption(this); 1651 }, 1652 }, 1653 }); 1654 }); 1655 }; 1656 1657 Module.highlightShares = function () { 1658 1659 const self = this; 1660 1661 if (!self.themeSettings.highlightShares || (window.matchMedia && window.matchMedia('(pointer: coarse)').matches)) { 1662 return; 1663 } 1664 1665 const config = { 1666 selectableElements: ['.is-highlight-shares'], 1667 twitterUsername: self.themeSettings.twitterName, 1668 facebook: !!self.themeSettings.highlightShareFacebook, 1669 twitter: !!self.themeSettings.highlightShareTwitter 1670 }; 1671 1672 const extra = self.themeSettings.highlightShareReddit ? [{ 1673 icon: '<i class="rbi rbi-reddit"></i>', 1674 url: 'https://reddit.com/submit?url=PAGE_URL&title=TEXT_SELECTION' 1675 }] : []; 1676 1677 Sharect.config(config).appendCustomShareButtons(extra).init(); 1678 } 1679 1680 /** 1681 * 1682 * @returns {boolean} 1683 */ 1684 Module.floatingVideo = function () { 1685 1686 const self = this; 1687 const floating = $('.floating-video').not('.is-loaded'); 1688 1689 if (floating.length === 0 || window.outerWidth < 1025) { 1690 return false; 1691 } 1692 1693 self.wPoint['Floating'] = new Waypoint({ 1694 element: floating, 1695 offset: -floating.height(), 1696 handler: function (direction) { 1697 self._body.find('.floating-video').addClass('is-loaded').removeClass('floating-activated'); 1698 self._body.find('.floating-close').remove(); 1699 if ('down' == direction) { 1700 this.element.addClass(' floating-activated'); 1701 this.element.find('.float-holder').prepend('<a class="floating-close close-popup-btn" href="#"><span class="close-icon"></span></a>'); 1702 } 1703 } 1704 }); 1705 } 1706 1707 Module.floatingVideoRemove = function () { 1708 const self = this; 1709 self._body.on('click', '.floating-close', function (e) { 1710 e.preventDefault(); 1711 e.stopPropagation(); 1712 self._body.find('.floating-video').removeClass('floating-activated'); 1713 self.wPoint['Floating'].destroy(); 1714 }) 1715 } 1716 1717 Module.siteAccessDetector = function () { 1718 const self = this; 1719 const method = self.themeSettings?.adDetectorMethod; 1720 1721 if (!method || self.siteAccessFlag || self.crwDetect()) { 1722 return; 1723 } 1724 1725 setTimeout(() => { 1726 if (self.siteAccessFlag) return; 1727 1728 switch (parseInt(method)) { 1729 case 1: 1730 self.baitElementDetector(); 1731 break; 1732 case 2: 1733 self.externalScriptDetector(); 1734 break; 1735 case 3: 1736 self.combinedDetector(); 1737 break; 1738 } 1739 }, 1500); 1740 }; 1741 1742 Module.baitElementDetector = function () { 1743 const self = this; 1744 const bait = self.createBaitElement(); 1745 document.body.appendChild(bait); 1746 1747 setTimeout(() => { 1748 const isBlocked = self.checkBaitElement(bait); 1749 bait.remove(); 1750 1751 if (isBlocked) { 1752 self.siteAccessFlag = true; 1753 $.magnificPopup.close(); 1754 setTimeout(() => { 1755 self.siteAccessNotification(); 1756 }, 200); 1757 } 1758 }, 100); 1759 }; 1760 1761 Module.externalScriptDetector = function () { 1762 const self = this; 1763 const testUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'; 1764 const script = document.createElement('script'); 1765 script.src = testUrl; 1766 script.async = true; 1767 1768 let completed = false; 1769 1770 const complete = (blocked) => { 1771 if (completed) return; 1772 completed = true; 1773 script.remove(); 1774 1775 if (blocked) { 1776 self.siteAccessFlag = true; 1777 $.magnificPopup.close(); 1778 setTimeout(() => { 1779 self.siteAccessNotification(); 1780 }, 200); 1781 } 1782 }; 1783 1784 script.onerror = () => complete(true); 1785 script.onload = () => complete(false); 1786 setTimeout(() => complete(true), 5000); 1787 1788 document.head.appendChild(script); 1789 }; 1790 1791 Module.combinedDetector = function () { 1792 const self = this; 1793 const bait = self.createBaitElement(); 1794 document.body.appendChild(bait); 1795 1796 setTimeout(() => { 1797 const baitBlocked = self.checkBaitElement(bait); 1798 bait.remove(); 1799 1800 if (baitBlocked) { 1801 self.siteAccessFlag = true; 1802 $.magnificPopup.close(); 1803 setTimeout(() => { 1804 self.siteAccessNotification(); 1805 }, 200); 1806 return; 1807 } 1808 1809 self.externalScriptDetector(); 1810 }, 100); 1811 }; 1812 1813 Module.createBaitElement = function () { 1814 const container = document.createElement('div'); 1815 container.id = 'rb-adcheck'; 1816 container.setAttribute('aria-hidden', 'true'); 1817 container.style.cssText = 'position:absolute;bottom:0;left:0;z-index:-1;pointer-events:none;overflow:hidden;'; 1818 1819 const inner = document.createElement('div'); 1820 inner.id = 'google_ads_iframe_test'; 1821 inner.className = 'adsbygoogle ad-slot adbanner ads-banner banner_ad ad-placeholder pub_300x250 textads adsbox'; 1822 inner.setAttribute('data-ad-slot', 'test'); 1823 inner.style.cssText = 'width:300px;height:250px;background:transparent;'; 1824 1825 container.appendChild(inner); 1826 return container; 1827 }; 1828 1829 Module.checkBaitElement = function (container) { 1830 const inner = container.querySelector('.adsbygoogle'); 1831 1832 if (!inner || !document.body.contains(inner)) { 1833 return true; 1834 } 1835 1836 const style = window.getComputedStyle(inner); 1837 const rect = inner.getBoundingClientRect(); 1838 1839 return ( 1840 rect.height < 1 || 1841 rect.width < 1 || 1842 style.display === 'none' || 1843 style.visibility === 'hidden' || 1844 parseFloat(style.opacity) === 0 || 1845 inner.offsetParent === null 1846 ); 1847 }; 1848 1849 Module.siteAccessNotification = function () { 1850 $.magnificPopup.open({ 1851 type: 'inline', 1852 preloader: false, 1853 showCloseBtn: false, 1854 closeBtnInside: false, 1855 enableEscapeKey: false, 1856 closeOnBgClick: false, 1857 removalDelay: 9999999, 1858 items: { 1859 src: $('#tmpl-rb-site-access').html(), 1860 type: 'inline' 1861 }, 1862 mainClass: 'rb-popup-center site-access-popup', 1863 fixedBgPos: true, 1864 fixedContentPos: true, 1865 }); 1866 1867 window.addEventListener('contextmenu', event => event.preventDefault()); 1868 } 1869 1870 /** build gallery lightbox */ 1871 Module.galleryLightbox = function () { 1872 1873 const self = this; 1874 if (!self.galleriesData) { 1875 return; 1876 } 1877 1878 $('.gallery-popup-trigger').on('click', function (e) { 1879 e.preventDefault(); 1880 e.stopPropagation(); 1881 1882 const target = $(this); 1883 const slideIndex = target.data('index'); 1884 1885 $.magnificPopup.open({ 1886 type: 'inline', 1887 mainClass: 'rb-gallery-popup rb-popup-center', 1888 closeMarkup: '<button title="%title%" class="mfp-close mfp-button"><i class="rbi rbi-close"></i></button>', 1889 closeOnBgClick: false, 1890 removalDelay: 400, 1891 showCloseBtn: true, 1892 fixedBgPos: true, 1893 fixedContentPos: true, 1894 preloader: false, 1895 gallery: { 1896 enabled: true, 1897 preload: [0, 2], 1898 arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-button mfp-arrow-%dir%"><i class="rbi rbi-%dir%"></i></button>', 1899 tCounter: '<span>%curr% / %total%</span>' 1900 }, 1901 callbacks: { 1902 open: function () { 1903 let itemsArray = Object.values(self.galleriesData); 1904 let targetIndex = itemsArray.findIndex(item => item.key === slideIndex); 1905 if (targetIndex !== -1) { 1906 $.magnificPopup.instance.goTo(targetIndex); 1907 } 1908 }, 1909 change: function () { 1910 1911 let imgContainer = $('.gallery-popup-content'); 1912 let loader = imgContainer.find('.rb-loader'); 1913 let img = imgContainer.find('img'); 1914 loader.show(); 1915 1916 if (!img.length) { 1917 loader.hide(); 1918 return; 1919 } 1920 1921 let loaderTimeout = setTimeout(() => { 1922 loader.fadeIn(200); 1923 }, 300); // Show loader only if image takes longer 300ms 1924 1925 img.on('load', function () { 1926 clearTimeout(loaderTimeout); // Prevent loader from showing if image loads within 300ms 1927 loader.hide(); 1928 }).on('error', function () { 1929 clearTimeout(loaderTimeout); 1930 loader.hide(); 1931 }); 1932 }, 1933 afterClose: function () { 1934 $.magnificPopup.instance.popupsCache = {}; 1935 }, 1936 buildControls: function () { 1937 if (this.arrowLeft && this.arrowRight) { 1938 this.contentContainer.find('.gallery-popup-nav').append(this.arrowLeft.add(this.arrowRight)); 1939 } 1940 } 1941 }, 1942 inline: { 1943 markup: 1944 '<div class="gallery-popup-header light-scheme">' + 1945 '<div class="mfp-counter"></div><div class="mfp-title h5"></div>' + 1946 '<div class="popup-header-right"><div class="mfp-close"></div></div>' + 1947 '</div><div class="gallery-popup-nav"></div>' + 1948 '<div class="gallery-popup-content"><i class="rb-loader"></i>' + 1949 '<div class="gallery-popup-image mfp-image"></div>' + 1950 '<div class="gallery-popup-entry light-scheme">' + 1951 '<div class="h4 mfp-excerpt"></div>' + 1952 '<div class="description-text mfp-description"></div>' + 1953 '</div>' + 1954 '</div>' 1955 }, 1956 items: Object.values(self.galleriesData) 1957 }); 1958 1959 return false; 1960 }); 1961 }; 1962 1963 /** single featured lightbox */ 1964 Module.singleFeaturedLightbox = function () { 1965 $('.featured-lightbox-trigger').on('click', function (e) { 1966 1967 e.preventDefault(); 1968 e.stopPropagation(); 1969 1970 const trigger = $(this); 1971 const source = '<img src="' + trigger.data('source') + '" alt="' + $(this).find('img').attr('alt') + '">'; 1972 const caption = trigger.data('caption'); 1973 const attribution = trigger.data('attribution'); 1974 1975 $.magnificPopup.open({ 1976 mainClass: 'rb-popup-center popup-no-overflow', 1977 closeOnBgClick: true, 1978 removalDelay: 400, 1979 showCloseBtn: true, 1980 fixedBgPos: true, 1981 fixedContentPos: true, 1982 preloader: false, 1983 closeMarkup: '<button title="%title%" class="mfp-close rb-popup-close"><i class="rbi rbi-close"></i></button>', 1984 callbacks: { 1985 afterClose: function () { 1986 $.magnificPopup.instance.popupsCache = {}; 1987 }, 1988 }, 1989 inline: { 1990 markup: 1991 '<div class="featured-popup-image"><div class="mfp-source"></div>' + 1992 '<div class="mfp-close rb-popup-close"></div></div>' + 1993 '<div class="gallery-popup-entry light-scheme">' + 1994 '<div class="h4 mfp-excerpt"></div>' + 1995 '<div class="description-text mfp-description"></div>' + 1996 '</div>' 1997 }, 1998 items: { 1999 source: source, 2000 excerpt: caption, 2001 description: attribution, 2002 }, 2003 }); 2004 }); 2005 } 2006 2007 /** Ajax pagination */ 2008 Module.paginationNextPrev = function () { 2009 const self = this; 2010 self._body.on('click', '.pagination-trigger', function (e) { 2011 2012 e.preventDefault(); 2013 e.stopPropagation(); 2014 const paginationTrigger = $(this); 2015 if (paginationTrigger.hasClass('is-disable')) { 2016 return; 2017 } 2018 2019 const block = paginationTrigger.parents('.block-wrap'); 2020 const uuid = block.attr('id'); 2021 2022 if (!self.ajaxData[uuid]) { 2023 self.ajaxData[uuid] = self.getBlockSettings(uuid); 2024 } 2025 if (self.ajaxData[uuid] && self.ajaxData[uuid].processing) { 2026 return; 2027 } 2028 self.ajaxData[uuid].processing = true; 2029 const type = paginationTrigger.data('type'); 2030 self.ajaxStartAnimation(block, 'replace'); 2031 self.ajaxReplaceLoad(block, uuid, type); 2032 }); 2033 } 2034 2035 Module.ajaxReplaceLoad = function (block, uuid, type) { 2036 2037 const self = this; 2038 2039 if (!self.ajaxData[uuid].paged) { 2040 self.ajaxData[uuid].paged = 1; 2041 } 2042 if ('prev' === type) { 2043 self.ajaxData[uuid].page_next = parseInt(self.ajaxData[uuid].paged) - 1; 2044 } else { 2045 self.ajaxData[uuid].page_next = parseInt(self.ajaxData[uuid].paged) + 1; 2046 } 2047 2048 const cacheID = self.cacheData.getCacheID(uuid, self.ajaxData[uuid].page_next); 2049 2050 /** use cache */
2051 if (self.cacheData.exist(cacheID)) { 2052 const cache = self.cacheData.get(cacheID); 2053 if ('undefined' !== typeof cache.paged) { 2054 self.ajaxData[uuid].paged = cache.paged; 2055 } 2056 setTimeout(function () { 2057 self.ajaxRenderHTML(block, uuid, cache, 'replace'); 2058 }, 200) 2059 2060 } else { 2061 /** POST AJAX */ 2062 $.ajax({ 2063 type: 'GET', 2064 url: self.ajaxURL, 2065 data: { 2066 action: 'rblivep', 2067 data: self.ajaxData[uuid] 2068 }, 2069 success: function (response) { 2070 response = JSON.parse(JSON.stringify(response)); 2071 if ('undefined' !== typeof response.paged) { 2072 self.ajaxData[uuid].paged = response.paged; 2073 } 2074 self.cacheData.set(cacheID, response); 2075 self.ajaxRenderHTML(block, uuid, response, 'replace'); 2076 } 2077 }); 2078 } 2079 } 2080 2081 Module.paginationLoadMore = function () { 2082 const self = this; 2083 self._body.on('click', '.loadmore-trigger', function (e) { 2084 2085 e.preventDefault(); 2086 e.stopPropagation(); 2087 2088 const paginationTrigger = $(this); 2089 if (paginationTrigger.hasClass('is-disable')) { 2090 return; 2091 } 2092 2093 const block = paginationTrigger.parents('.block-wrap'); 2094 const uuid = block.attr('id'); 2095 2096 if (!self.ajaxData[uuid]) { 2097 self.ajaxData[uuid] = self.getBlockSettings(uuid); 2098 } 2099 if (self.ajaxData[uuid] && self.ajaxData[uuid].processing) { 2100 return; 2101 } 2102 self.ajaxData[uuid].processing = true; 2103 self.ajaxStartAnimation(block, 'append'); 2104 self.ajaxAppendLoad(block, uuid); 2105 }) 2106 } 2107 2108 Module.paginationInfinite = function () { 2109 2110 const self = this; 2111 2112 const infiniteElements = $('.pagination-infinite'); 2113 if (infiniteElements.length > 0) { 2114 infiniteElements.each(function () { 2115 const paginationTrigger = $(this); 2116 if (!paginationTrigger.hasClass('is-disable')) { 2117 const block = paginationTrigger.parents('.block-wrap'); 2118 if ((block.hasClass('is-hoz-scroll') || block.hasClass('is-mhoz-scroll') || block.hasClass('is-thoz-scroll')) && window.outerWidth < 1025) { 2119 paginationTrigger.addClass('is-disable'); 2120 return; 2121 } 2122 const uuid = block.attr('id'); 2123 const wPointID = 'infinite' + uuid; 2124 if (!self.ajaxData[uuid]) { 2125 self.ajaxData[uuid] = self.getBlockSettings(uuid); 2126 } 2127 const params = { 2128 element: paginationTrigger, 2129 offset: '120%', 2130 handler: function (direction) { 2131 if (self.ajaxData[uuid] && self.ajaxData[uuid].processing) { 2132 return; 2133 } 2134 if ('down' == direction) { 2135 self.ajaxData[uuid].processing = true; 2136 self.ajaxStartAnimation(block, 'append'); 2137 self.ajaxAppendLoad(block, uuid); 2138 } 2139 } 2140 } 2141 self.wPoint[wPointID] = new Waypoint(params); 2142 } 2143 }); 2144 } 2145 } 2146 2147 Module.ajaxAppendLoad = function (block, uuid) { 2148 const self = this; 2149 if (!self.ajaxData[uuid].paged) { 2150 self.ajaxData[uuid].paged = 1; 2151 } 2152 if (self.ajaxData[uuid].paged >= self.ajaxData[uuid].page_max) { 2153 return; 2154 } 2155 self.ajaxData[uuid].page_next = parseInt(self.ajaxData[uuid].paged) + 1; 2156 $.ajax({
2157 type: 'GET', 2158 url: self.ajaxURL, 2159 data: { 2160 action: 'rblivep', 2161 data: self.ajaxData[uuid] 2162 }, 2163 success: function (response) { 2164 response = JSON.parse(JSON.stringify(response)); 2165 if ('undefined' !== typeof response.paged) { 2166 self.ajaxData[uuid].paged = response.paged; 2167 } 2168 if ('undefined' !== typeof response.notice) { 2169 response.content = response.content + response.notice; 2170 } 2171 self.ajaxRenderHTML(block, uuid, response, 'append'); 2172 } 2173 }); 2174 } 2175 2176 Module.liveSearch = function () { 2177 2178 const liveSearch = $('.live-search-form'); 2179 if (liveSearch.length === 0) { 2180 return; 2181 } 2182 2183 const self = this; 2184 2185 liveSearch.each(function () { 2186 const liveSearchEl = $(this); 2187 const input = liveSearchEl.find('input[type="text"]'); 2188 const responseWrap = liveSearchEl.find('.live-search-response'); 2189 const animation = liveSearchEl.find('.live-search-animation'); 2190 const limit = liveSearchEl.data('limit'); 2191 const search = liveSearchEl.data('search'); 2192 const follow = liveSearchEl.data('follow'); 2193 const tax = liveSearchEl.data('tax'); 2194 const dsource = liveSearchEl.data('dsource'); 2195 const ptype = liveSearchEl.data('ptype'); 2196 2197 input.attr('autocomplete', 'off'); 2198 2199 input.on('focus', function () { 2200 const param = $(this).val(); 2201 if (param && !responseWrap.is(':empty')) { 2202 responseWrap.css('height', 'auto').fadeIn(200); 2203 } 2204 }); 2205 2206 const delay = (function () { 2207 let timer = 0; 2208 return function (callback, ms) { 2209 clearTimeout(timer); 2210 timer = setTimeout(callback, ms); 2211 }; 2212 })(); 2213 2214 input.keyup(function () { 2215 const param = $(this).val(); 2216 delay(function () { 2217 if (param) { 2218 liveSearchEl.addClass('search-loading'); 2219 setTimeout(function () { 2220 animation.fadeIn(100); 2221 }, 120); 2222 2223 $.ajax({
2224 type: 'GET', 2225 url: self.ajaxURL, 2226 data: { 2227 action: 'rbsearch', 2228 s: param, 2229 limit: limit, 2230 search: search, 2231 follow: follow, 2232 tax: tax, 2233 dsource: dsource, 2234 ptype: ptype, 2235 }, 2236 success: function (data) { 2237 data = $.parseJSON(JSON.stringify(data)); 2238 animation.fadeOut(200); 2239 setTimeout(function () { 2240 liveSearchEl.removeClass('search-loading'); 2241 }, 200); 2242 responseWrap.hide().empty().css('height', responseWrap.height()); 2243 responseWrap.html(data); 2244 if ('category' === search && follow && typeof FOXIZ_PERSONALIZE !== 'undefined') { 2245 FOXIZ_PERSONALIZE.syncLayoutCategories(); 2246 } 2247 responseWrap.css('height', 'auto').fadeIn(200); 2248 } 2249 }); 2250 } else { 2251 responseWrap.fadeOut(200, function () { 2252 responseWrap.empty().css('height', 'auto'); 2253 }); 2254 } 2255 }, 300); 2256 }) 2257 }); 2258 } 2259 2260 /** personalized block */ 2261 Module.personalizeBlocks = function () { 2262 const self = this; 2263 const elements = $('.is-ajax-block'); 2264 if (elements.length > 0) { 2265 const blockRequests = elements.map(function () { 2266 const block = $(this); 2267 const uuid = block.attr('id'); 2268 if (!self.ajaxData[uuid]) { 2269 self.ajaxData[uuid] = self.getBlockSettings(uuid); 2270 } 2271 2272 if (self.ajaxData[uuid].content_source && 2273 self.ajaxData[uuid].content_source === 'recommended' && 2274 typeof foxizQueriedIDs !== 'undefined' && foxizQueriedIDs.data 2275 ) { 2276 self.ajaxData[uuid].post_not_in = foxizQueriedIDs.data; 2277 } 2278 2279 self.ajaxData[uuid].uID = self.getStorage('RBUUID', '0'); 2280 2281 return $.ajax({ 2282 type: 'GET', 2283 url: self.ajaxURL, 2284 data: { 2285 action: 'rbpersonalizeb', 2286 data: self.ajaxData[uuid] 2287 } 2288 }); 2289 }); 2290 2291 Promise.all(blockRequests).then(responses => { 2292 responses.forEach((response, index) => { 2293 const block = $(elements[index]); 2294 block.html(response).fadeIn(200); 2295 block.dequeue(); 2296 }); 2297 self.reloadBlockFunc(); 2298 }); 2299 } 2300 }; 2301 2302 /** personalized categories */ 2303 Module.personalizeCategories = function () { 2304 2305 const self = this; 2306 const elements = $('.is-ajax-categories'); 2307 if (elements.length > 0) { 2308 const categoryRequests = elements.map(function () { 2309 const block = $(this); 2310 const uuid = block.attr('id'); 2311 if (!self.ajaxData[uuid]) { 2312 self.ajaxData[uuid] = self.getBlockSettings(uuid); 2313 } 2314 return $.ajax({
2315 type: 'GET', 2316 url: self.ajaxURL, 2317 data: { 2318 action: 'rbpersonalizecat', 2319 data: self.ajaxData[uuid] 2320 } 2321 }); 2322 }); 2323 2324 Promise.all(categoryRequests).then(responses => { 2325 responses.forEach((response, index) => { 2326 const block = $(elements[index]); 2327 block.html(response).fadeIn(200); 2328 block.dequeue(); 2329 }); 2330 2331 if (typeof FOXIZ_PERSONALIZE !== 'undefined') { 2332 FOXIZ_PERSONALIZE.syncLayoutCategories(); 2333 } 2334 self.reloadBlockFunc(); 2335 }); 2336 } 2337 }; 2338 2339 Module.readingCollect = function () { 2340 const self = this; 2341 if (self.themeSettings.yesReadingHis === undefined) { 2342 return; 2343 } 2344 $.ajax({
2345 type: 'GET', 2346 url: self.ajaxURL, 2347 data: { 2348 action: 'rbcollect', 2349 id: self.themeSettings.yesReadingHis 2350 } 2351 }); 2352 }; 2353 2354 /** header notification */ 2355 Module.newsNotification = function () { 2356 2357 const notificationWrapper = $('.rb-notification'); 2358 if (notificationWrapper.length < 1) { 2359 return false; 2360 } 2361 2362 const self = this; 2363 const storageKey = this.personalizeUID + '-notification'; 2364 const dot = $('.notification-info'); 2365 2366 // Get reload interval (now in minutes, default 15) 2367 let reload = notificationWrapper.data('interval'); 2368 if (!reload || isNaN(reload) || reload <= 0) { 2369 reload = 15; 2370 } 2371 2372 // Helper: count NEW post IDs (in current but not in viewed) 2373 function countNewPosts(currentIds, viewedIds) { 2374 if (!currentIds) return 0; 2375 if (!viewedIds) return currentIds.split(',').length; 2376 2377 const current = currentIds.split(','); 2378 const viewed = viewedIds.split(','); 2379 let count = 0; 2380 for (let i = 0; i < current.length; i++) { 2381 if (viewed.indexOf(current[i]) === -1) { 2382 count++; 2383 } 2384 } 2385 return count; 2386 } 2387 2388 // Get cached data (contains: content, count, ids, viewedIds, ttl) 2389 const cached = self.getStorage(storageKey); 2390 2391 // Show cached content immediately for instant UX 2392 if (cached && cached.content) { 2393 notificationWrapper.append(cached.content); 2394 // Show count of NEW posts only (not total) 2395 const newCount = countNewPosts(cached.ids, cached.viewedIds); 2396 if (newCount > 0) { 2397 dot.append(newCount); 2398 dot.css('opacity', 1); 2399 } 2400 } 2401 2402 // Hide dot when user opens notification dropdown 2403 $('.notification-trigger').on('click', function () { 2404 dot.css('opacity', 0).empty(); 2405 // Mark current IDs as viewed 2406 const current = self.getStorage(storageKey); 2407 if (current && current.ids) { 2408 current.viewedIds = current.ids; 2409 self.setStorage(storageKey, current); 2410 } 2411 }); 2412 2413 // Check if refresh needed (expired or no cache) 2414 const isExpired = !cached || !cached.ttl || Date.now() > cached.ttl; 2415 2416 if (isExpired) { 2417 $.ajax({
2418 type: 'GET', 2419 url: self.ajaxURL, 2420 data: {action: 'rbnotification'}, 2421 success: function (response) { 2422 response = $.parseJSON(JSON.stringify(response)); 2423 2424 const newIds = response.ids || ''; 2425 const oldIds = cached ? (cached.ids || '') : ''; 2426 const viewedIds = cached ? (cached.viewedIds || '') : ''; 2427 2428 // Store new data with TTL in minutes (preserve viewedIds) 2429 self.setStorage(storageKey, { 2430 content: response.content, 2431 count: response.count, 2432 ids: newIds, 2433 viewedIds: viewedIds, 2434 ttl: Date.now() + reload * 60000 2435 }); 2436 2437 // Update DOM if: no local cache (first load) OR post IDs changed 2438 if (!cached || newIds !== oldIds) { 2439 notificationWrapper.empty().append(response.content); 2440 dot.empty(); 2441 // Show count of NEW posts only (or total if first load) 2442 const newCount = countNewPosts(newIds, viewedIds); 2443 if (newCount > 0) { 2444 dot.append(newCount); 2445 dot.css('opacity', 1); 2446 } 2447 } 2448 } 2449 }); 2450 } 2451 }; 2452 2453 /** register cache object */ 2454 Module.cacheData = { 2455 2456 data: {}, 2457 get: function (id) { 2458 return this.data[id]; 2459 }, 2460 2461 set: function (id, data) { 2462 this.remove(id); 2463 this.data[id] = data; 2464 }, 2465 2466 remove: function (id) { 2467 delete this.data[id]; 2468 }, 2469 2470 getCacheID: function (blockID, currentPage) { 2471 return JSON.stringify('RB_' + blockID + '_' + currentPage); 2472 }, 2473 2474 exist: function (id) { 2475 return this.data.hasOwnProperty(id) && this.data[id] !== null; 2476 } 2477 } 2478 2479 /** 2480 * ajax start animation 2481 * @param block 2482 * @param action 2483 */ 2484 Module.ajaxStartAnimation = function (block, action) { 2485 2486 const inner = block.find('.block-inner'); 2487 block.find('.pagination-trigger').addClass('is-disable'); 2488 inner.stop(); 2489 2490 if ('replace' === action) { 2491 inner.css('min-height', inner.outerHeight()); 2492 inner.fadeTo('200', 0.05); 2493 inner.after('<i class="rb-loader loader-absolute"></i>'); 2494 } else { 2495 block.find('.loadmore-trigger').addClass('loading'); 2496 block.find('.rb-loader').css({'display': 'block'}).delay(200).animate({opacity: 1}, 200); 2497 } 2498 } 2499 2500 /** 2501 * render ajax 2502 * @param block 2503 * @param uuid 2504 * @param response 2505 * @param action 2506 */ 2507 Module.ajaxRenderHTML = function (block, uuid, response, action) { 2508 2509 const self = this; 2510 2511 block.delay(50).queue(function () { 2512 const uuid = block.attr('id'); 2513 const inner = block.find('.block-inner'); 2514 block.find('.pagination-trigger').removeClass('is-disable'); 2515 inner.stop(); 2516 2517 if ('replace' === action) { 2518 inner.html(response.content); 2519 block.find('.rb-loader').animate({opacity: 0}, 200, function () { 2520 $(this).remove(); 2521 }) 2522 inner.css('min-height', ''); 2523 inner.fadeTo(200, 1); 2524 2525 } else { 2526 const content = $(response.content); 2527 inner.append(content); 2528 content.addClass('is-invisible'); 2529 content.addClass('opacity-animate'); 2530 2531 block.find('.rb-loader').animate({opacity: 0}, 200, function () { 2532 $(this).css({'display': 'none'}); 2533 }); 2534 setTimeout(function () { 2535 content.removeClass('is-invisible'); 2536 }, 200); 2537 block.find('.loadmore-trigger').removeClass('loading'); 2538 } 2539 2540 /** reload */ 2541 self.ajaxTriggerState(block, uuid); 2542 self.ajaxData[uuid].processing = false; 2543 block.dequeue(); 2544 self.reloadBlockFunc(); 2545 }); 2546 } 2547 2548 /** 2549 * set 2550 * @param block 2551 * @param uuid 2552 */ 2553 Module.ajaxTriggerState = function (block, uuid) { 2554 const self = this; 2555 block.find('.pagination-trigger').removeClass('is-disable'); 2556 if (self.ajaxData[uuid].paged < 2) { 2557 block.find('[data-type="prev"]').addClass('is-disable'); 2558 } else if (self.ajaxData[uuid].paged >= self.ajaxData[uuid].page_max) { 2559 block.find('[data-type="next"]').addClass('is-disable'); 2560 block.find('.loadmore-trigger').addClass('is-disable').hide(); 2561 block.find('.pagination-infinite').addClass('is-disable').hide(); 2562 } 2563 } 2564 2565 Module.getBlockSettings = function (uuid) { 2566 const settings = typeof window[uuid] !== 'undefined' ? window[uuid] : undefined; 2567 return this.cleanNull(settings); 2568 } 2569 2570 Module.cleanNull = function (data) { 2571 if (typeof data === 'string') { 2572 return data; 2573 } 2574 2575 if (data && typeof data === 'object') {
2576 Object.keys(data).forEach(key => { 2577 if (data[key] === '' || data[key] === null) { 2578 delete data[key]; 2579 } 2580 }); 2581 } 2582 2583 return data; 2584 }; 2585 2586 /* SINGLE INFINITE */ 2587 Module.singleInfiniteLoadNext = function () { 2588 2589 const infiniteWrapper = $('#single-post-infinite'); 2590 const self = this; 2591 2592 if (!infiniteWrapper.length || self.disabledLoadNext()) { 2593 return; 2594 } 2595 2596 self.singleLoadNextCounter = 1; 2597 self.singleLoadNextLimit = self.themeSettings?.singleLoadNextLimit ? parseInt(self.themeSettings.singleLoadNextLimit, 10) : 20; 2598 2599 const infiniteLoadPoint = $('#single-infinite-point'); 2600 const animationIcon = infiniteLoadPoint.find('.rb-loader'); 2601 const rootURL = new URL(window.location.href); 2602 const rootGetParams = rootURL.searchParams; 2603 2604 const loadNextParams = { 2605 element: infiniteLoadPoint, 2606 offset: '125%', 2607 handler: function (direction) { 2608 if (self.ajaxData.singleProcessing || direction === 'up' || self.singleLoadNextCounter > self.singleLoadNextLimit) { 2609 return; 2610 } 2611 const nextPostURL = new URL(infiniteWrapper.data('nextposturl')); 2612 nextPostURL.searchParams.set('rbsnp', '1'); 2613 if (rootGetParams) { 2614 rootGetParams.forEach((value, key) => { 2615 if (key !== 'rbsnp' && 'p' !== key) { 2616 nextPostURL.searchParams.set(key, value); 2617 } 2618 }); 2619 } 2620 self.ajaxData.singleProcessing = true; 2621 animationIcon.css('display', 'block').animate({opacity: 1}, 200); 2622 2623 $.ajax({
2624 type: 'GET', 2625 url: nextPostURL.toString(), 2626 dataType: 'html', 2627 success: function (response) { 2628 response = $('<div id="temp-dom"></div>').append($.parseHTML(response)).find('.single-post-outer'); 2629 const nextPostURL = response.data('nextposturl'); 2630 2631 if (nextPostURL) { 2632 infiniteWrapper.data('nextposturl', nextPostURL); 2633 } else { 2634 infiniteWrapper.removeAttr('id'); 2635 infiniteLoadPoint.remove(); 2636 } 2637 2638 animationIcon.animate({opacity: 0}, 200).delay(200).css('display', 'none'); 2639 infiniteWrapper.append(response); 2640 self.ajaxData.singleProcessing = false; 2641 self.singleLoadNextCounter++; 2642 2643 setTimeout(function () { 2644 self.reInitAll(); 2645 if (typeof FOXIZ_CORE_SCRIPT !== 'undefined') { 2646 FOXIZ_CORE_SCRIPT.loadGoogleAds(response); 2647 FOXIZ_CORE_SCRIPT.loadInstagram(response); 2648 FOXIZ_CORE_SCRIPT.loadTwttr(); 2649 } 2650 }, 1); 2651 } 2652 }); 2653 } 2654 }; 2655 2656 self.wPoint.ajaxSingleNextPosts = new Waypoint(loadNextParams); 2657 }; 2658 2659 Module.singleScrollRefresh = function () { 2660 2661 const infiniteWrapper = $('#single-post-infinite'); 2662 if (!infiniteWrapper.length) { 2663 return; 2664 } 2665 const self = this; 2666 self.articleData = []; 2667 const articleOuter = infiniteWrapper.find('.single-post-outer'); 2668 2669 if (articleOuter.length > 0) { 2670 self.inviewPostID = articleOuter.eq(0).data('postid'); 2671 2672 articleOuter.each(function () { 2673 const article = $(this); 2674 const itemData = { 2675 postID: article.data('postid'), 2676 postURL: article.data('postlink'), 2677 postTitle: article.find('h1.s-title').text(), 2678 shareList: article.find('.sticky-share-list-buffer').html(), 2679 top: article.offset().top, 2680 bottom: article.offset().top + article.outerHeight(true) 2681 }; 2682 2683 if (self.readIndicator.length > 0) { 2684 const content = article.find('.rbct').eq(0); 2685 itemData.indicatorTop = content.offset().top; 2686 itemData.indicatorHeight = content.outerHeight(true) - self._window.height(); 2687 } 2688 self.articleData.push(itemData); 2689 }); 2690 2691 const onScroll = () => { 2692 self.animationFrame(self.scrollToUpdateArticle.bind(self)); 2693 }; 2694 if (window.addEventListener) { 2695 window.addEventListener('scroll', onScroll, false); 2696 } 2697 } 2698 } 2699 2700 /** scrollToUpdateArticle */ 2701 Module.scrollToUpdateArticle = function () { 2702 const self = this; 2703 const scroll = self._window.scrollTop(); 2704 2705 self.articleData.every(article => { 2706 if (scroll > (article.top + 5) && scroll < (article.bottom - 5)) { 2707 if (article.indicatorTop) { 2708 self.readIndicatorPercent = Math.min(((scroll - article.indicatorTop) / article.indicatorHeight) * 100, 100); 2709 if (self.readIndicatorPercent <= 100) { 2710 self.readIndicator.css('width', `${self.readIndicatorPercent}%`); 2711 } 2712 } 2713 2714 if (article.postID !== self.inviewPostID) { 2715 self.inviewPostID = article.postID; 2716 if (article.postURL) { 2717 history.replaceState(null, null, article.postURL); 2718 } 2719 document.title = article.postTitle; 2720 $('.single-post-outer').removeClass('activated'); 2721 $('[data-postid="' + article.postID + '"]').addClass('activated'); 2722 $('#s-title-sticky .sticky-title').hide().html(article.postTitle).fadeIn(300); 2723 $('#s-title-sticky .sticky-share-list').html(article.shareList); 2724 self._body.find('.floating-video').removeClass('floating-activated'); 2725 2726 if (typeof FOXIZ_CORE_SCRIPT !== 'undefined') { 2727 FOXIZ_CORE_SCRIPT.updateGA(article); 2728 } 2729 } 2730 return false; 2731 } 2732 2733 return true; 2734 2735 }); 2736 } 2737 2738 /** 2739 * @returns {boolean} 2740 */ 2741 Module.crwDetect = function () { 2742 const botPatterns = [ 2743 /alexa|altavista|ask jeeves|attentio|baiduspider|bingbot|chtml generic|crawler|fastmobilecrawl|feedfetcher-google|firefly|froogle|gigabot|googlebot|googlebot-mobile|heritrix|httrack|ia_archiver|irlbot|iescholar|infoseek|jumpbot|linkcheck|lycos|mediapartners|mediobot|motionbot|msnbot|mshots|openbot|pss-webkit-request|pythumbnail|scooter|slurp|snapbot|spider|taptubot|technoratisnoop|teoma|twiceler|yahooseeker|yaho
2743oysmcm|yammybot|ahrefsbot|pingdom.com_bot|kraken|yandexbot|twitterbot|tweetmemebot|openhosebot|queryseekerspider|linkdexbot|grokkit-crawler|livelapbot|germcrawler|domaintunocrawler|grapeshotcrawler|cloudflare-alwaysonline/i 2744 ]; 2745 2746 const userAgent = navigator.userAgent; 2747 return botPatterns.some(pattern => pattern.test(userAgent)); 2748 }; 2749 2750 /** 2751 * 2752 * @returns {boolean} 2753 */ 2754 Module.disabledLoadNext = function () { 2755 2756 if (this.themeSettings.crwLoadNext) { 2757 return false; 2758 } 2759 2760 return this.crwDetect(); 2761 } 2762 2763 /** productQuantity */ 2764 Module.productQuantity = function () { 2765 this._document.on('click', '.quantity .quantity-btn', function (e) { 2766 2767 e.preventDefault(); 2768 e.stopPropagation(); 2769 2770 const button = $(this); 2771 const input = button.parent().find('input'); 2772 2773 let step = 1; 2774 let min = 1; 2775 let max = 9999; 2776 let value_old = parseInt(input.val()); 2777 let value_new = parseInt(input.val()); 2778 2779 if (input.attr('step')) { 2780 step = parseInt(input.attr('step')); 2781 } 2782 2783 if (input.attr('min')) { 2784 min = parseInt(input.attr('min')); 2785 } 2786 2787 if (input.attr('max')) { 2788 max = parseInt(input.attr('max')); 2789 } 2790 2791 if (button.hasClass('up')) { 2792 if (value_old < max) { 2793 value_new = value_old + step; 2794 } else { 2795 value_new = 1; 2796 } 2797 } else if (button.hasClass('down')) { 2798 if (value_old > min) { 2799 value_new = value_old - step; 2800 } else { 2801 value_new = 0; 2802 } 2803 } 2804 2805 if (!input.attr('disabled')) { 2806 input.val(value_new).change(); 2807 } 2808 }); 2809 } 2810 2811 Module.cartNotification = function () { 2812 const self = this; 2813 const element = $('#add-cart-popup'); 2814 2815 self._body.on('added_to_cart', function () { 2816 element.fadeIn(200); 2817 self.cartNotificationTimeOut = setTimeout(function () { 2818 element.fadeOut(200); 2819 }, 5000); 2820 self.hoveringNotification(element); 2821 }); 2822 } 2823 2824 Module.hoveringNotification = function (element) { 2825 const self = this; 2826 2827 element.on('mouseenter', function () { 2828 clearTimeout(self.cartNotificationTimeOut); 2829 }); 2830 2831 element.on('mouseleave', function () { 2832 setTimeout(function () { 2833 element.fadeOut(200); 2834 }, 1500); 2835 }); 2836 } 2837 2838 /** like/dislike */ 2839 Module.likeToggle = function () { 2840 2841 const self = this; 2842 let reaction = ''; 2843 self._body.on('click', '.like-trigger, .dislike-trigger', function (e) { 2844 2845 e.preventDefault(); 2846 e.stopPropagation(); 2847 2848 const target = $(this); 2849 const wrap = target.parent('[data-like]'); 2850 const pid = wrap.data('like'); 2851 2852 if (!pid || self.isProgress) return; 2853 2854 self.isProgress = true; 2855 const storageKey = self.getLikeKey(pid); 2856 const isLike = target.hasClass('like-trigger'); 2857 const isDislike = target.hasClass('dislike-trigger'); 2858 const sibEl = target.siblings(); 2859 const likeCountEl = wrap.find('.like-count'); 2860 const dislikeCountEl = wrap.find('.dislike-count'); 2861 let likeCountText = likeCountEl.text(); 2862 let dislikeCountText = dislikeCountEl.text(); 2863 2864 if (isLike) { 2865 if (!target.hasClass('triggered')) { 2866 reaction = 'like'; 2867 if (!/[kKmM]/.test(likeCountText)) { 2868 likeCountText = parseInt(likeCountText); 2869 if (isNaN(likeCountText)) { 2870 likeCountText = 0; 2871 } 2872 likeCountEl.text(likeCountText + 1); 2873 } 2874 target.addClass('triggered'); 2875 2876 if (sibEl.hasClass('triggered')) { 2877 sibEl.removeClass('triggered'); 2878 if (!/[kKmM]/.test(dislikeCountText)) { 2879 dislikeCountText = parseInt(dislikeCountText) - 1; 2880 if (isNaN(dislikeCountText) || dislikeCountText < 1) { 2881 dislikeCountText = ''; 2882 } 2883 dislikeCountEl.text(dislikeCountText); 2884 } 2885 } 2886 self.setStorage(storageKey, 'like'); 2887 } else { 2888 reaction = 'rmlike'; 2889 if (!/[kKmM]/.test(likeCountText)) { 2890 likeCountText = parseInt(likeCountText) - 1; 2891 if (isNaN(likeCountText) || likeCountText < 1) { 2892 likeCountText = ''; 2893 } 2894 likeCountEl.text(likeCountText); 2895 } 2896 target.removeClass('triggered'); 2897 self.deleteStorage(storageKey); 2898 } 2899 } else if (isDislike) { 2900 if (!target.hasClass('triggered')) { 2901 reaction = 'dislike'; 2902 if (!/[kKmM]/.test(dislikeCountText)) { 2903 dislikeCountText = parseInt(dislikeCountText); 2904 if (isNaN(dislikeCountText)) { 2905 dislikeCountText = 0; 2906 } 2907 dislikeCountEl.text(dislikeCountText + 1); 2908 } 2909 target.addClass('triggered'); 2910 if (sibEl.hasClass('triggered')) { 2911 sibEl.removeClass('triggered'); 2912 if (!/[kKmM]/.test(likeCountText)) { 2913 likeCountText = parseInt(likeCountText) - 1; 2914 if (isNaN(likeCountText) || likeCountText < 1) { 2915 likeCountText = ''; 2916 } 2917 likeCountEl.text(likeCountText); 2918 } 2919 } 2920 self.setStorage(storageKey, 'dislike'); 2921 } else { 2922 reaction = 'rmdislike'; 2923 if (!/[kKmM]/.test(dislikeCountText)) { 2924 likeCountText = parseInt(likeCountText) - 1; 2925 if (isNaN(likeCountText) || likeCountText < 1) { 2926 likeCountText = ''; 2927 } 2928 dislikeCountEl.text(likeCountText); 2929 } 2930 target.removeClass('triggered'); 2931 self.deleteStorage(storageKey); 2932 } 2933 } 2934 2935 $.ajax({
2936 type: 'GET', 2937 url: self.ajaxURL, 2938 data: { 2939 uuid: self.personalizeUID, 2940 action: 'rbvoting', 2941 value: reaction, 2942 pid: pid, 2943 }, 2944 complete: () => { 2945 self.isProgress = false; 2946 } 2947 }) 2948 }) 2949 } 2950 2951 /** sync layout */ 2952 Module.syncLayoutLike = function () { 2953 2954 this.isProgress = true; 2955 const likeElements = document.querySelectorAll('[data-like]:not(.loaded)'); 2956 const jsCount = this._body.hasClass('is-jscount'); 2957 let count, countEl; 2958 2959 for (const el of likeElements) { 2960 el.classList.add('loaded'); 2961 const key = this.getLikeKey(el.getAttribute('data-like')); 2962 const triggered = this.getStorage(key); 2963 2964 if (!triggered) continue; 2965 2966 const likeEl = el.querySelector('.el-like'); 2967 const dislikeEl = el.querySelector('.el-dislike'); 2968 2969 if (!likeEl || !dislikeEl) continue; 2970 2971 if (triggered === 'like') { 2972 likeEl.classList.add('triggered'); 2973 countEl = jsCount ? likeEl.querySelector('.like-count') : null; 2974 if (countEl) { 2975 count = parseInt(countEl.textContent.trim()) || 0; 2976 countEl.textContent = count + 1; 2977 } 2978 } else if (triggered === 'dislike') { 2979 dislikeEl.classList.add('triggered'); 2980 countEl = jsCount ? dislikeEl.querySelector('.dislike-count') : null; 2981 if (countEl) { 2982 count = parseInt(countEl.textContent.trim()) || 0; 2983 countEl.textContent = count + 1; 2984 } 2985 } 2986 } 2987 2988 this.isProgress = false; 2989 }; 2990 2991 /** like key */ 2992 Module.getLikeKey = function (id) { 2993 return this.personalizeUID + '-like-' + id; 2994 } 2995 2996 /** live blog */ 2997 Module.liveBlog = function () { 2998 const self = this; 2999 3000 const liveEntry = $('.rb-live-entry'); 3001 3002 if (liveEntry.length === 0) { 3003 return false; 3004 } 3005 3006 let intervalId; 3007 let delayTimeoutId; 3008 const interval = Math.min(1800, Math.max(15, this.themeSettings.liveInterval || 1800)); 3009 const liveSwitcher = $('#live-interval-switcher'); 3010 const storedSetting = this.getStorage('liveIntervalCheckbox'); 3011 3012 // Start the regular interval (no initial delay) 3013 const startInterval = () => { 3014 clearInterval(intervalId); 3015 intervalId = setInterval(() => this.updateLiveBlog(liveEntry), interval * 1000); 3016 }; 3017 3018 // Stop all timers 3019 const stopAll = () => { 3020 clearInterval(intervalId); 3021 clearTimeout(delayTimeoutId); 3022 }; 3023 3024 // Handle manual toggle with 5s delay to avoid rapid triggering 3025 const handleToggle = () => { 3026 stopAll(); 3027 3028 if (liveSwitcher.prop('checked')) { 3029 // Delay 3s before first load, then continue with regular interval 3030 delayTimeoutId = setTimeout(() => { 3031 this.updateLiveBlog(liveEntry); 3032 startInterval(); 3033 }, 3000); 3034 self.setStorage('liveIntervalCheckbox', 'yes'); 3035 } else { 3036 self.setStorage('liveIntervalCheckbox', 'no'); 3037 } 3038 }; 3039 3040 // Initialize from stored setting 3041 if (storedSetting !== null) { 3042 liveSwitcher.prop('checked', storedSetting === 'yes'); 3043 } else { 3044 self.setStorage('liveIntervalCheckbox', 'yes'); 3045 } 3046 3047 // On page load: start interval immediately if checked (no delay) 3048 if (liveSwitcher.prop('checked')) { 3049 startInterval(); 3050 } 3051 3052 // On manual toggle: use 5s delay 3053 liveSwitcher.on('change', handleToggle); 3054 }; 3055 3056 Module.updateLiveBlog = function (liveEntry) { 3057 3058 const self = this; 3059 const liveURL = new URL(window.location.href); 3060 liveURL.searchParams.set('rblive', '1'); 3061 $.ajax({
3062 type: 'GET', 3063 url: liveURL.toString(), 3064 dataType: 'html', 3065 success: function (response) { 3066 response = $('<div id="temp-dom"></div>').append($.parseHTML(response)).find('#rb-live-content'); 3067 liveEntry.html(response.html()); 3068 const liveCountElement = liveEntry.prev().find('.live-count'); 3069 if (liveCountElement.length) { 3070 liveCountElement.text(response.data('total')); 3071 } 3072 setTimeout(function () { 3073 self.reInitAll(); 3074 if (typeof FOXIZ_CORE_SCRIPT !== 'undefined') { 3075 FOXIZ_CORE_SCRIPT.loadGoogleAds(response); 3076 FOXIZ_CORE_SCRIPT.loadInstagram(response); 3077 FOXIZ_CORE_SCRIPT.loadTwttr(); 3078 } 3079 }, 1); 3080 } 3081 }); 3082 } 3083 3084 Module.accordion = function () { 3085 $('.gb-accordion').each(function () { 3086 const accordion = $(this); 3087 if (accordion.hasClass('yesLoaded')) return; 3088 3089 accordion.addClass('yesLoaded'); 3090 const accordionItems = accordion.find('.gb-accordion-item'); 3091 3092 if (accordion.hasClass('yes-open')) { 3093 accordionItems.first().addClass('active').find('.accordion-item-content').css('display', 'block'); 3094 } 3095 3096 accordion.on('click', '.accordion-item-header', function (e) { 3097 e.preventDefault(); 3098 3099 const header = $(this); 3100 const item = header.closest('.gb-accordion-item'); 3101 const content = item.find('.accordion-item-content'); 3102 3103 if (item.hasClass('active')) { 3104 item.removeClass('active'); 3105 content.stop().slideUp(200); 3106 } else { 3107 const activeItem = accordionItems.filter('.active'); 3108 activeItem.removeClass('active').find('.accordion-item-content').stop().slideUp(200); 3109 item.addClass('active'); 3110 content.stop().slideDown(200); 3111 } 3112 }); 3113 }); 3114 }; 3115 3116 Module.resIframeClassic = function () { 3117 3118 if (!document.body.classList.contains('res-iframe-classic')) return 3119 const iframes = document.querySelectorAll('.rbct iframe'); 3120 iframes.forEach(iframe => { 3121 const parent = iframe.parentElement; 3122 const grandParent = parent.parentElement; 3123 const greatGrandParent = grandParent.parentElement; 3124 3125 if ([parent, grandParent, greatGrandParent].some(element => { 3126 const classNames = Array.from(element.classList); 3127 return classNames.some(className => className.indexOf('wp-block') !== -1); 3128 })) return; 3129 3130 if (!iframe.parentElement.classList.contains('rb-video-ires')) { 3131 if (iframe.src.includes('youtube.com') || iframe.src.includes('youtu.be') || iframe.src.includes('vimeo.com') || iframe.src.includes('dailymotion.com')) { 3132 iframe.parentElement.classList.add('rb-video-ires'); 3133 } 3134 } 3135 }); 3136 } 3137 3138 Module.taxBasedAccordion = function () { 3139 3140 const self = this; 3141 $('.block-tax-accordion').each(function () { 3142 const accordion = $(this); 3143 if (accordion.hasClass('is-loaded')) { 3144 return; 3145 } 3146 accordion.addClass('is-loaded'); 3147 const accordionItems = accordion.find('.tax-accordion-item'); 3148 const lastOpenedTab = self.getStorage(accordion.attr('id') + '_lastOpenedTab', null); 3149 3150 if (lastOpenedTab) { 3151 const tabToOpen = accordion.find('[data-tab="' + lastOpenedTab + '"] .tax-accordion-sub'); 3152 if (tabToOpen.length !== 0) { 3153 tabToOpen.show(); 3154 } 3155 } 3156 3157 accordionItems.each(function () { 3158 const item = $(this); 3159 const trigger = item.find('.tax-accordion-trigger'); 3160 const subMenu = item.find('.tax-accordion-sub'); 3161 3162 trigger.click(function () { 3163 if (!subMenu.is(':visible')) { 3164 accordion.find('.tax-accordion-sub').not(subMenu).slideUp(); 3165 } 3166 subMenu.slideToggle(function () { 3167 if (subMenu.is(':visible')) { 3168 self.setStorage(accordion.attr('id') + '_lastOpenedTab', item.attr('data-tab')); 3169 } else { 3170 self.deleteStorage(accordion.attr('id') + '_lastOpenedTab'); 3171 } 3172 }); 3173 }); 3174 }); 3175 }); 3176 }; 3177 3178 3179 Module.sequentialGalleryDisplay = function () { 3180 const galleries = Array.from(document.querySelectorAll('.gallery-animated'));
3181 galleries.forEach(gallery => { 3182 const images = Array.from(gallery.querySelectorAll('.e-gallery-item')); 3183 new Waypoint({ 3184 element: gallery, 3185 handler: function (direction) { 3186 if (direction === 'down') { 3187 images.forEach((image, index) => { 3188 requestAnimationFrame(() => { 3189 setTimeout(() => { 3190 image.classList.add('gallery-visible'); 3191 }, index * 120); 3192 }); 3193 }); 3194 this.destroy(); 3195 } 3196 }, 3197 offset: '90%' 3198 }); 3199 }); 3200 }; 3201 3202 3203 Module.reloadCaptchaPopups = function (delay = 50) { 3204 setTimeout(() => { 3205 const $content = $($.magnificPopup?.instance?.content || []); 3206 if (!$content.length) return; 3207 3208 const removeDuplicateCaptchas = form => { 3209 const seen = new Set(); 3210 $(form) 3211 .find('.g-recaptcha, .h-captcha, .cf-turnstile, .turnstile-widget, .frc-captcha, [data-arkose-public-key], .arkose-enforcement, .geetest_holder, .geetest_panel') 3212 .each(function () { 3213 const cls = this.className; 3214 const type = ['g-recaptcha', 'h-captcha', 'cf-turnstile', 'turnstile-widget', 'frc-captcha', 'arkose', 'geetest'] 3215 .find(t => cls.includes(t) || $(this).data('arkose-public-key') || $(this).hasClass('arkose-enforcement')); 3216 if (!type) return; 3217 const key = `${type}`; 3218 if (seen.has(key)) { 3219 $(this).remove(); 3220 } else { 3221 seen.add(key); 3222 } 3223 }); 3224 }; 3225 3226 try { 3227 // Remove duplicates per form 3228 $content.find('form').each(function () { 3229 removeDuplicateCaptchas(this); 3230 }); 3231 3232 // Google reCAPTCHA 3233 if (typeof grecaptcha !== 'undefined' && grecaptcha?.reset) { 3234 $content.find('.g-recaptcha').each(function () { 3235 const wid = this.dataset.widgetId; 3236 if (wid) { 3237 try { grecaptcha.reset(Number(wid)); } catch {} 3238 } 3239 }); 3240 } 3241 3242 // Cloudflare Turnstile 3243 if (typeof turnstile !== 'undefined' && turnstile?.reset) { 3244 $content.find('.cf-turnstile, .turnstile-widget').each(function () { 3245 const iframe = this.querySelector('iframe'); 3246 const wid = iframe?.dataset?.wid; 3247 if (wid) { 3248 try { turnstile.reset(wid); } catch {} 3249 } 3250 }); 3251 } 3252 3253 // hCaptcha 3254 if (typeof hcaptcha !== 'undefined' && hcaptcha?.reset) { 3255 $content.find('.h-captcha').each(function () { 3256 const wid = this.dataset.widgetId; 3257 if (wid) { 3258 try { hcaptcha.reset(Number(wid)); } catch {} 3259 } 3260 }); 3261 } 3262 3263 // FriendlyCaptcha 3264 if (typeof friendlycaptcha !== 'undefined' && friendlycaptcha?.widget) { 3265 $content.find('.frc-captcha').each(function () { 3266 const stored = $(this).data('frc-widget'); 3267 if (stored?.reset) { 3268 try { stored.reset(); } catch {} 3269 } 3270 }); 3271 } 3272 3273 // Arkose Labs 3274 if (window?.arkose?.reset || typeof ECArkose !== 'undefined') { 3275 const $arkoseEls = $content.find('[data-arkose-public-key], .arkose-enforcement'); 3276 if ($arkoseEls.length) { 3277 try { 3278 window?.arkose?.reset?.(); 3279 ECArkose?.reset?.(); 3280 } catch {} 3281 } 3282 } 3283 3284 // GeeTest 3285 if (typeof initGeetest !== 'undefined' || typeof GeetInit !== 'undefined') { 3286 $content.find('.geetest_holder, .geetest_panel').each(function () { 3287 const inst = this.geetestInstance; 3288 if (inst?.reset) { 3289 try { inst.reset(); } catch {} 3290 } 3291 }); 3292 } 3293 3294 } catch (err) {} 3295 }, delay); 3296 }; 3297 3298 return Module; 3299 3300 }(FOXIZ_MAIN_SCRIPT || {}, jQuery) 3301) 3302 3303/** init */ 3304jQuery(document).ready(function ($) {
3305 FOXIZ_MAIN_SCRIPT.init(); 3306}); 3307 3308/** Elementor editor */ 3309jQuery(window).on('elementor/frontend/init', function () { 3310 3311 if (typeof elementorFrontend !== 'undefined' && typeof elementorFrontend.isEditMode === 'function' && elementorFrontend.isEditMode()) { 3312 FOXIZ_MAIN_SCRIPT.isElementorEditor = true; 3313 FOXIZ_MAIN_SCRIPT.editorDarkModeInit = false; 3314 3315 elementorFrontend.hooks.addAction('frontend/element_ready/widget', FOXIZ_MAIN_SCRIPT.initElementor); 3316 } 3317});
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.