1/** 2 * @package Helix Ultimate Framework 3 * @author JoomShaper https://www.joomshaper.com 4 * @copyright Copyright (c) 2010 - 2023 JoomShaper 5 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or Later 6 */ 7 8// Preloader 9jQuery(window).on('load', function () { 10 if (jQuery('.sp-loader-with-logo').length > 0) { 11 move() 12 } 13 jQuery('.sp-pre-loader').fadeOut(500, function () { 14 jQuery(this).remove() 15 }) 16}) 17 18/** 19 * Move the progress bar 20 */ 21function move() { 22 var elem = document.getElementById('line-load') 23 var width = 1 24 var id = setInterval(frame, 10) 25 function frame() { 26 if (width >= 100) { 27 clearInterval(id) 28 } else { 29 width++ 30 elem.style.width = width + '%' 31 } 32 } 33} 34 35jQuery(function ($) { 36 /** 37 * Helix settings data 38 * 39 */ 40 var settings = Joomla.getOptions('data') || {} 41 42 /** 43 * sticky header 44 * 45 * @param {string} className the header className 46 */ 47 var handleStickiness = function (className, offsetTop) { 48 if ($('body:not(.layout-edit-iframe)').hasClass(className)) { 49 var $header = $('#sp-header') 50 var headerHeight = $header.outerHeight() 51 var $stickyHeaderPlaceholder = $('.sticky-header-placeholder') 52 let $stickyOffset = '100' 53 54 if ( 55 settings.header !== undefined && 56 settings.header.stickyOffset !== undefined 57 ) { 58 $stickyOffset = settings.header.stickyOffset || '100' 59 } 60 61 var stickyHeader = function () { 62 var scrollTop = $(window).scrollTop() 63 if (scrollTop >= offsetTop + Number($stickyOffset)) { 64 $header.addClass('header-sticky') 65 $stickyHeaderPlaceholder.height(headerHeight) 66 } else { 67 if ($header.hasClass('header-sticky')) { 68 $header.removeClass('header-sticky') 69 $stickyHeaderPlaceholder.height('inherit') 70 } 71 } 72 } 73 74 stickyHeader() 75 $(window).scroll(function () { 76 stickyHeader() 77 }) 78 79 if ($('body').hasClass('layout-boxed')) { 80 var windowWidth = $header.parent().outerWidth() 81 $header.css({ 'max-width': windowWidth, left: 'auto' }) 82 } 83 } else { 84 var $header = $('#sp-header') 85 if ($header.hasClass('header-sticky')) { 86 $header.removeClass('header-sticky') 87 } 88 $(window).off('scroll') 89 } 90 } 91 92 /** 93 * Calculate the header offset based on the 94 * backend preview iframe site and real site. 95 * 96 * @return integer The offset value 97 */ 98 function getHeaderOffset() { 99 /** 100 * Real site header offset top 101 * 102 */ 103 let $header = $('#sp-header') 104 let stickyHeaderTop = $header.offset().top 105 106 /** 107 * Backend edit preview iframe header offset top 108 * 109 */ 110 let $backHeader = $('body.back-panel').find('#sp-header') 111 let backPanelStickyHeaderTop = null 112 113 /** 114 * If the class .back-panel exists, 115 * that means this is from backend preview frame, 116 * then get the offset top, as it varies with the original one. 117 * 118 */ 119 if ($backHeader.length > 0) { 120 backPanelStickyHeaderTop = $backHeader.offset().top 121 } 122 123 // By Default the header offset is the original header top 124 let headerOffset = stickyHeaderTop 125 126 /** 127 * If back panel sticky header top has value rather than null 128 * that means the device type is changes from desktop to table or mobile or vice-versa. 129 * If value found then subtract the settings topbar height from the offset top. 130 * 131 */ 132 if (backPanelStickyHeaderTop !== null) { 133 headerOffset = backPanelStickyHeaderTop - settings.topbarHeight 134 headerOffset = headerOffset < 0 ? stickyHeaderTop : headerOffset 135 } 136 137 return headerOffset 138 } 139 140 const headerExist = $('#sp-header') 141 if (headerExist.length > 0) { 142 handleStickiness('sticky-header', getHeaderOffset()) 143 } 144 145 // go to top 146 $(window).scroll(function () { 147 if ($(this).scrollTop() > 100) { 148 $('.sp-scroll-up').fadeIn() 149 } else { 150 $('.sp-scroll-up').fadeOut(400) 151 } 152 }) 153 154 $('.sp-scroll-up').click(function () { 155 $('html, body').animate( 156 { 157 scrollTop: -60, 158 }, 159 600, 160 ) 161 return false 162 }) 163 164 //mega menu 165 $('.sp-megamenu-wrapper') 166 .parent() 167 .parent() 168 .css('position', 'static') 169 .parent() 170 .css('position', 'relative') 171 $('.sp-menu-full').each(function () { 172 $(this).parent().addClass('menu-justify') 173 }) 174 175 // Offcanvs 176 $('#offcanvas-toggler').on('click', function (event) { 177 event.preventDefault() 178 $('.offcanvas-init').addClass('offcanvas-active') 179 }) 180 181 $('.offcanvas-toggler-secondary').on('click', function (event) { 182 event.preventDefault() 183 $('.offcanvas-init').addClass('offcanvas-active') 184 }) 185 186 $('.offcanvas-toggler-full').on('click', function (event) { 187 event.preventDefault() 188 $('.offcanvas-init').addClass('offcanvas-active full-offcanvas') 189 }) 190 191 $('.close-offcanvas, .offcanvas-overlay').on('click', function (event) { 192 event.preventDefault() 193 $('.offcanvas-init').removeClass('offcanvas-active full-offcanvas') 194 }) 195 196 $(document).on('click', '.offcanvas-inner .menu-toggler', function (event) { 197 event.preventDefault() 198 $(this) 199 .closest('.menu-parent') 200 .toggleClass('menu-parent-open') 201 .find('>.menu-child') 202 .slideToggle(400) 203 }) 204 205 // Modal Menu
206 if ($('#modal-menu').length > 0) { 207 let $modalToggler = $('#modal-menu-toggler') 208 let $modalMenu = $('#modal-menu') 209 let $body = $('body') 210 211 $modalToggler.on('click', function (e) { 212 e.preventDefault() 213 $modalMenu.toggleClass('active') 214 $body.toggleClass('modal-menu-active') 215 $(this).toggleClass('active') 216 }) 217 218 // modal menu close with escape 219 $(document).keyup(function (e) { 220 if (e.key == 'Escape') { 221 $modalMenu.removeClass('active') 222 $modalToggler.removeClass('active') 223 $body.removeClass('modal-menu-active') 224 } 225 }) 226 } 227 228 // Tooltip 229 const tooltipTriggerList = [].slice.call( 230 document.querySelectorAll('[data-bs-toggle="tooltip"], .hasTooltip'), 231 ) 232 tooltipTriggerList.map(function (tooltipTriggerEl) { 233 return new bootstrap.Tooltip(tooltipTriggerEl, { 234 html: true, 235 }) 236 }) 237 238 // Popover 239 const popoverTriggerList = [].slice.call( 240 document.querySelectorAll('[data-bs-toggle="popover"], .hasPopover'), 241 ) 242 popoverTriggerList.map(function (popoverTriggerEl) { 243 return new bootstrap.Popover(popoverTriggerEl) 244 }) 245 246 // Article Ajax voting 247 $('.article-ratings .rating-star').on('click', function (event) { 248 event.preventDefault() 249 var $parent = $(this).closest('.article-ratings') 250 251 var request = { 252 option: 'com_ajax', 253 template: template, 254 action: 'rating', 255 rating: $(this).data('number'), 256 article_id: $parent.data('id'), 257 format: 'json', 258 } 259 260 $.ajax({ 261 type: 'POST', 262 data: request, 263 beforeSend: function () { 264 $parent.find('.fa-spinner').show() 265 }, 266 success: function (response) { 267 var data = $.parseJSON(response) 268 $parent.find('.ratings-count').text(data.message) 269 $parent.find('.fa-spinner').hide() 270 271 if (data.status) { 272 $parent.find('.rating-symbol').html(data.ratings) 273 } 274 275 setTimeout(function () { 276 $parent 277 .find('.ratings-count') 278 .text('(' + data.rating_count + ')') 279 }, 3000) 280 }, 281 }) 282 }) 283 284 // Cookie consent 285 $('.sp-cookie-allow').on('click', function (event) { 286 event.preventDefault() 287 288 var date = new Date() 289 date.setTime(date.getTime() + 30 * 24 * 60 * 60 * 1000) 290 var expires = '; expires=' + date.toGMTString() 291 document.cookie = 'spcookie_status=ok' + expires + '; path=/' 292 293 $(this).closest('.sp-cookie-consent').fadeOut() 294 }) 295 296 $('.btn-group label:not(.active)').click(function () { 297 var label = $(this) 298 var input = $('#' + label.attr('for')) 299 300 if (!input.prop('checked')) { 301 label 302 .closest('.btn-group') 303 .find('label') 304 .removeClass('active btn-success btn-danger btn-primary') 305 if (input.val() === '') { 306 label.addClass('active btn-primary') 307 } else if (input.val() == 0) { 308 label.addClass('active btn-danger') 309 } else { 310 label.addClass('active btn-success') 311 } 312 input.prop('checked', true) 313 input.trigger('change') 314 } 315 var parent = $(this).parents('#attrib-helix_ultimate_blog_options') 316 if (parent) { 317 showCategoryItems(parent, input.val()) 318 } 319 }) 320 $('.btn-group input[checked=checked]').each(function () { 321 if ($(this).val() == '') { 322 $('label[for=' + $(this).attr('id') + ']').addClass( 323 'active btn btn-primary', 324 ) 325 } else if ($(this).val() == 0) { 326 $('label[for=' + $(this).attr('id') + ']').addClass( 327 'active btn btn-danger', 328 ) 329 } else { 330 $('label[for=' + $(this).attr('id') + ']').addClass( 331 'active btn btn-success', 332 ) 333 } 334 var parent = $(this).parents('#attrib-helix_ultimate_blog_options') 335 if (parent) { 336 parent.find('*[data-showon]').each(function () { 337 $(this).hide() 338 }) 339 } 340 }) 341 342 function showCategoryItems(parent, value) { 343 var controlGroup = parent.find('*[data-showon]') 344 345 controlGroup.each(function () { 346 var data = $(this).attr('data-showon') 347 data = typeof data !== 'undefined' ? JSON.parse(data) : [] 348 if (data.length > 0) { 349 if ( 350 typeof data[0].values !== 'undefined' && 351 data[0].values.includes(value) 352 ) { 353 $(this).slideDown() 354 } else { 355 $(this).hide() 356 } 357 } 358 }) 359 } 360 361 $(window).on('scroll', function () { 362 var scrollBar = $('.sp-reading-progress-bar') 363 if (scrollBar.length > 0) { 364 var s = $(window).scrollTop(), 365 d = $(document).height(), 366 c = $(window).height() 367 var scrollPercent = (s / (d - c)) * 100 368 const position = scrollBar.data('position') 369 if (position === 'top') { 370 // var sticky = $('.header-sticky'); 371 // if( sticky.length > 0 ){ 372 // sticky.css({ top: scrollBar.height() }) 373 // }else{ 374 // sticky.css({ top: 0 }) 375 // } 376 } 377 scrollBar.css({ width: `${scrollPercent}%` }) 378 } 379 }) 380 381 // Error Alert close issue fix for Joomla 3 382 var observer = new MutationObserver(function (mutations) { 383 $('#system-message-container .alert .close').attr( 384 'data-bs-dismiss', 385 'alert', 386 ) 387 }) 388 var target = document.querySelector('#system-message-container') 389 observer.observe(target, { 390 attributes: true, 391 }) 392 393 $('.sp-menu-item.sp-has-child > a> img').each(function () { 394 let left = Math.floor($(this).parent().parent().offset().left) 395 let menu = Math.floor($('#sp-menu').offset().left) 396 let logo = Math.floor($('#sp-logo').offset().left) 397 let gap = menu - logo 398 const leftValue = left - menu 399 400 $(this).css({ 401 left: -leftValue - gap + 15 + 'px', 402 position: 'absolute', 403 }) 404 }) 405 406 $('.border-bottom-left-element') 407 .parent() 408 .css({ position: 'relative', 'z-index': '2' }) 409 $('.border-top-left-element') 410 .parent() 411 .css({ position: 'relative', 'z-index': '2' }) 412 $('.border-top-right-element') 413 .parent() 414 .css({ position: 'relative', 'z-index': '2' }) 415 $('.border-bottom-right-element') 416 .parent() 417 .css({ position: 'relative', 'z-index': '2' }) 418 419 // Infinite Scrolling 420 const articlesScroller = document.querySelector('.animated-scroller') 421 if (articlesScroller) { 422 let currentLeftValue = 0 423 let interval = null 424 const gap = 2 // Define the gap 425 426 function animationStart() { 427 interval = setInterval(animationLoop, 10) 428 } 429 430 function animationStop() { 431 clearInterval(interval) 432 } 433 434 articlesScroller.addEventListener('mouseover', animationStop) 435 articlesScroller.addEventListener('mouseout', animationStart) 436 437 function animationLoop() { 438 const firstListItem = 439 articlesScroller.querySelector('div:first-child') 440 const rightSideOfFirstItem = 441 firstListItem.getBoundingClientRect().right 442 443 if (rightSideOfFirstItem < 0) { 444 articlesScroller.appendChild(firstListItem) 445 currentLeftValue += firstListItem.clientWidth + gap 446 } 447 448 articlesScroller.style.marginLeft = `${currentLeftValue}px` 449 currentLeftValue-- 450 } 451 452 animationStart() 453 } 454})
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.