1;(function ($) { 2 "use strict"; 3 4 $.fn.get_transparent_selector = function get_transparent_selector(){ 5 let transparent_header_selector = $(this).closest('.hthb-notification.hthb-pos--top[data-transparent_header_selector]').last().data('transparent_header_selector'); 6 if($(this).closest('.hthb-notification.hthb-pos--top').hasClass('hthb-transparent')){ 7 return transparent_header_selector; 8 } 9 10 return false; 11 } 12 13 $.fn.add_transparent_header_spacing = function add_transparent_header_spacing(top_notification_height){ 14 if( $('body').find('#wpadminbar').length ){ 15 top_notification_height = Number.parseInt(top_notification_height + $('body').find('#wpadminbar').height()); 16 } 17 } 18 19 function calculate_top_zero(){ 20 if( $('body').find('#wpadminbar').length ){ 21 return '32px'; 22 } else{ 23 return '0px'; 24 } 25 } 26 27 var timeout = 400; 28 $(window).on('load',function(){ 29 var top_notification_height = Number.parseInt($('.hthb-notification.hthb-pos--top').last().height()), 30 bottom_notification_height = $('.hthb-notification.hthb-pos--bottom').last().height(), 31 left_wall_notification_width = $('.hthb-notification.hthb-pos--left-wall').last().width(), 32 right_wall_notification_width = $('.hthb-notification.hthb-pos--right-wall').last().width(); 33 34 var position; 35 36 // if load as minimized disabled 37 $('.hthb-notification.hthb-state--open').each(function(){ 38 position = $(this).getPostion(); 39 40 if( position == 'top' ){ 41 $('body').addClass('hthb hthb-pt--' + top_notification_height ); 42 if( $(this).get_transparent_selector() ){ 43 44 $($(this).get_transparent_selector()).addClass('hthb-top-unset'); 45 $($(this).get_transparent_selector()).css( {'top':'unset'} ); 46 47 } 48 } else if( position == 'bottom'){ 49 $('body').css('padding-bottom', bottom_notification_height + 'px'); 50 } 51 52 // Implement how many time to show 53 var time_to_show = $(this).data('time_to_show'), 54 id = $(this).data('id') ? '_' + $(this).data('id') : '', 55 coockie_count = Cookies.get('hashbarpro_cookiecount' + id), 56 hashbarpro_oldcookie = Cookies.get('hashbarpro_oldcookie' + id); 57 58 if( time_to_show && time_to_show > 0 ){ 59 60 if(document.cookie.indexOf("hashbarpro_oldcookie" + id) >= 0){ 61 if(time_to_show == hashbarpro_oldcookie && coockie_count){ 62 coockie_count++; 63 Cookies.set('hashbarpro_cookiecount' + id, coockie_count, { expires: 7 }); 64 } else { 65 Cookies.set('hashbarpro_oldcookie' + id, time_to_show, { expires: 7 }); 66 Cookies.set('hashbarpro_cookiecount' + id, 1, { expires: 7 }); 67 } 68 } else { 69 Cookies.set('hashbarpro_oldcookie' + id, time_to_show, { expires: 7 }); 70 Cookies.set('hashbarpro_cookiecount' + id, 1, { expires: 7 }); 71 } 72 } 73 74 if( coockie_count > time_to_show ){ 75 $(this).css({'display': 'none'}); 76 $(this).removeClass('hthb-state--open').addClass('hthb-state--minimized'); 77 78 if( position == 'top' ){ 79 $('body').removeClass('hthb'); 80 } 81 } 82 83 }); 84 85 // Load as mimimized if option is set to minimized 86 $('.hthb-notification.hthb-state--minimized').each(function(){ 87 var position = $(this).getPostion(); 88 if( position == 'top' || position == 'top-promo' || position == 'bottom' || position == 'bottom-promo' ){ 89 $(this).find('.hthb-row').css('display', 'none'); 90 } 91 92 }); 93 94 // Left/right wall 95 $('.hthb-notification.hthb-state--minimized').each(function(){ 96 var position = $(this).getPostion(); 97 if( position == 'left-wall' ){ 98 $(this).css('left', '-' + left_wall_notification_width + 'px' ); 99 } else if( position == 'right-wall' ){ 100 $(this).css('right', '-' + right_wall_notification_width + 'px' ); 101 } 102 103 }); 104 105 setTimeout(function(){ 106 $('.hthb-notification').addClass('hthb-loaded'); 107 }, timeout ); 108 109 $('.hthb-notification').each(function() { 110 const delay_time = $(this).attr('data-delay_time'); 111 if(+delay_time) { 112 setTimeout(() => { 113 $(this).showNotification( top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width ); 114 }, +delay_time*1000); 115 } 116 }) 117 118 // When click close button 119 $('.hthb-close-toggle').on('click', function(){ 120 const $hthb_id = $(this).closest('.hthb-notification')[0].dataset.id; 121 let $expire_time = +hashbar_localize.cookies_expire_time 122 if(hashbar_localize.cookies_expire_type === 'hours') { 123 $expire_time = $expire_time/24; 124 } 125 if(hashbar_localize.cookies_expire_type === 'minutes') { 126 $expire_time = $expire_time/1440; 127 } 128 129 $(this).minimizeNotification( top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width); 130 131 // Keep closed 132 if( hashbar_localize.bar_keep_closed == '1' ){ 133 Cookies.set(`keep_closed_bar_${$hthb_id}`, '1', { expires: $expire_time, path: '/' }); 134 } 135 136 // Don't show forever 137 if( hashbar_localize.dont_show_bar_after_close == '1' ) { 138 Cookies.set( `dont_show_bar_${$hthb_id}`, '1', { expires: $expire_time, path: '/' } ); 139 } 140 }); 141 142 // When clicked open button 143 $('.hthb-open-toggle').on('click', function(){ 144 $(this).showNotification( top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width ); 145 }); 146 147 // When scroll position matched with a notification 148 // Show the notifications 149 var window_inner_height = $(window).height(), 150 page_height = $('body').height(); 151 152 let current_scroll_position = window.pageYOffset || document.documentElement.scrollTop, 153 current_scroll_position_percent = current_scroll_position / scroll_pos_max * 100; 154 current_scroll_position_percent = Number.parseInt(current_scroll_position_percent); 155 156 var scroll_pos_max = $(document).height() - $(window).height(); 157 158 $(window).on('scroll', function(e){ 159 current_scroll_position = $(window).scrollTop(), 160 current_scroll_position_percent = current_scroll_position / scroll_pos_max * 100; 161 current_scroll_position_percent = Number.parseInt(current_scroll_position_percent); 162 163 $(`.hthb-scroll`).each(function(){ 164 let scroll_to_show = $(this).data('scroll_to_show'), 165 scroll_to_hide = $(this).data('scroll_to_hide'), 166 hthb_id = $(this)[0].dataset.id; 167 168 $(this).trigger_notification_on_scroll(hthb_id, scroll_to_show, scroll_to_hide, current_scroll_position, scroll_pos_max); 169 }); 170 }); 171 }); 172 173 /** 174 * Calculate % of a given value. 175 * For example, If the give value is 1000 & we want to know the 75% of it. 176 * It will return 750 as the result. 177 * 178 * @param number percent_amount, % amount. 179 * @param number percent_of, Total amount from where the % should be calculated. 180 * @return number 181 */ 182 function percent_of(percent_amount, percent_of){ 183 percent_of = Number.parseInt(percent_of); 184 percent_amount = Number.parseInt(percent_amount); 185 186 return percent_of * percent_amount / 100; 187 } 188 189 $.fn.getPostion = function(){ 190 if(this.closest('.hthb-notification').hasClass('hthb-pos--top')){ 191 return 'top'; 192 } 193 194 if(this.closest('.hthb-notification').hasClass('hthb-pos--bottom')){ 195 return 'bottom'; 196 } 197 198 if(this.closest('.hthb-notification').hasClass('hthb-pos--left-wall')){ 199 return 'left-wall'; 200 } 201 202 if(this.closest('.hthb-notification').hasClass('hthb-pos--right-wall')){ 203 return 'right-wall'; 204 } 205 206 if(this.closest('.hthb-notification').hasClass('hthb-pos--bottom-promo')){ 207 return 'bottom-promo'; 208 } 209 210 if(this.closest('.hthb-notification').hasClass('hthb-pos--top-promo')){ 211 return 'top-promo'; 212 } 213 } 214 215 $.fn.minimizeNotification = function(top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width){ 216 var postion = this.getPostion(), 217 left_wall_notification_width = this.closest('.hthb-notification').width(), 218 right_wall_notification_width = this.closest('.hthb-notification').width(); 219 220 this.closest('.hthb-notification').removeClass('hthb-state--open'); 221 this.closest('.hthb-notification').addClass('hthb-state--minimized'); 222 223 if(postion != 'left-wall' && postion != 'right-wall'){ 224 this.closest('.hthb-notification').find('.hthb-row').slideToggle(); 225 } 226 227 if( postion == 'top' ){ 228 $('body').removeClass('hthb'); 229 230 // for sticky 231 if( this.get_transparent_selector() ){ 232 $(this.get_transparent_selector()).addClass('hthb-top-unset'); 233 $(this.get_transparent_selector()).css({'top': calculate_top_zero()}); 234 } 235 } else if( postion == 'bottom' ){ 236 $('body').css('padding-bottom', ''); 237 } else if( postion == 'left-wall' ){ 238 this.closest('.hthb-notification').css('left', '-' + left_wall_notification_width + 'px' ); 239 } else if( postion == 'right-wall' ){ 240 this.closest('.hthb-notification').css('right', '-' + right_wall_notification_width + 'px' ); 241 } 242 } 243 244 $.fn.showNotification = function(top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width){ 245 var postion = this.getPostion(), 246 left_wall_notification_width = this.closest('.hthb-notification').width(), 247 right_wall_notification_width = this.closest('.hthb-notification').width(); 248 249 this.closest('.hthb-notification').removeClass('hthb-state--minimized'); 250 this.closest('.hthb-notification').addClass('hthb-state--open'); 251 252 if(postion != 'left-wall' && postion != 'right-wall'){ 253 this.closest('.hthb-notification').find('.hthb-row').slideToggle(); 254 } 255 256 if( postion == 'top' ){ 257 $('body').addClass('hthb hthb-pt--'+ top_notification_height ); 258 259 // for sticky 260 if( this.get_transparent_selector() ){ 261 $(this.get_transparent_selector()).addClass('hthb-top-unset'); 262 $(this.get_transparent_selector()).css({'top': 'unset'}); 263 } 264 } else if( postion == 'bottom' ){ 265 $('body').css('padding-bottom', bottom_notification_height + 'px'); 266 } else if( postion == 'left-wall' ){ 267 this.closest('.hthb-notification').css('left', ''); 268 } else if( postion == 'right-wall' ){ 269 this.closest('.hthb-notification').css('right', ''); 270 } 271 } 272 273 $.fn.trigger_click_on_open_button = function(){ 274 $(this).addClass('hthb-trigger-open-clicked').removeClass('hthb-trigger-close-clicked'); 275 $(this).find('.hthb-open-toggle').trigger('click'); 276 } 277 278 $.fn.trigger_click_on_close_button = function(){ 279 $(this).removeClass('hthb-trigger-open-clicked').addClass('hthb-trigger-close-clicked'); 280 $(this).find('.hthb-close-toggle').trigger('click'); 281 } 282 283 $.fn.check_keep_close_bar = function(id){ 284 var keep_closed_bar = Cookies.get(`keep_closed_bar_${id}`); 285 if( hashbar_localize.bar_keep_closed === '1' && keep_closed_bar){ 286 return false;
287 }else{ 288 return true; 289 } 290 } 291 292 $.fn.trigger_notification_on_scroll = function( id, scroll_to_show, scroll_to_hide, current_scroll_position, scroll_pos_max ){ 293 if( (scroll_to_show && typeof scroll_to_show == 'string' && scroll_to_show.indexOf('%')) > 0 && (scroll_to_hide && typeof scroll_to_hide == 'string' && scroll_to_hide.indexOf('%')) > 1 ){ 294 scroll_to_show = Number.parseInt(scroll_to_show); 295 scroll_to_hide = Number.parseInt(scroll_to_hide); 296 // 20% , 80% 297 298 if(current_scroll_position > percent_of(scroll_to_show, scroll_pos_max) && current_scroll_position < percent_of(scroll_to_hide, scroll_pos_max) ){ 299 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 300 if($(this).check_keep_close_bar(id)){ 301 $(this).trigger_click_on_open_button(); // show 302 } 303 } 304 } else{ 305 if( !$(this).is('.hthb-state--minimized') ){ 306 $(this).trigger_click_on_close_button(); // hide 307 } 308 } 309 } else if( (scroll_to_show && typeof scroll_to_show == 'string' && scroll_to_show.indexOf('%')) && (scroll_to_hide === '' || scroll_to_hide == undefined) ){ 310 scroll_to_show = Number.parseInt(scroll_to_show); 311 // 20% , ''/undefined 312 313 if( current_scroll_position > percent_of(scroll_to_show, scroll_pos_max) ){ 314 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 315 if($(this).check_keep_close_bar(id)){ 316 $(this).trigger_click_on_open_button(); // show 317 } 318 } 319 } else { 320 if( !$(this).is('.hthb-state--minimized') ){ 321 $(this).trigger_click_on_close_button(); // hide 322 } 323 } 324 } else if( (scroll_to_show && typeof scroll_to_show == 'number') && (scroll_to_hide && typeof scroll_to_hide == 'string')){ 325 // 300 , 80% 326 327 if( current_scroll_position > scroll_to_show && current_scroll_position < percent_of(scroll_to_hide, scroll_pos_max) ){ 328 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 329 if($(this).check_keep_close_bar(id)){ 330 $(this).trigger_click_on_open_button(); // show 331 } 332 } 333 } else{ 334 if( !$(this).is('.hthb-state--minimized') ){ 335 $(this).trigger_click_on_close_button(); // hide 336 } 337 } 338 339 } else if( (scroll_to_show === '' || scroll_to_show == undefined) && (scroll_to_hide && typeof scroll_to_hide == 'string' && scroll_to_hide.indexOf('%')) ){ 340 scroll_to_hide = Number.parseInt(scroll_to_hide); 341 // empty / undefined , 90% 342 343 if( current_scroll_position > percent_of(scroll_to_hide, scroll_pos_max) ){ 344 if( !$(this).is('.hthb-state--minimized') ){ 345 $(this).trigger_click_on_close_button(); // hide 346 } 347 } else{ 348 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 349 if($(this).check_keep_close_bar(id)){ 350 $(this).trigger_click_on_open_button(); // show 351 } 352 } 353 } 354 355 } else if( (scroll_to_show && typeof scroll_to_show == 'number') && (scroll_to_hide === '' || scroll_to_hide == undefined) ){ 356 // 300 , empty/undefined 357 if( current_scroll_position < scroll_to_show ){ 358 if( !$(this).is('.hthb-state--minimized') ){ 359 $(this).trigger_click_on_close_button(); // hide 360 } 361 362 } else{ 363 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 364 if($(this).check_keep_close_bar(id)){ 365 $(this).trigger_click_on_open_button(); // show 366 } 367 } 368 } 369 370 } else { 371 } 372 } 373 374 $(document).ready(function(){ 375 $(".hthb-countdown").each(function(){ 376 var countdown_id = "#"+$(this).attr('id')+" .hthb-countdown-section .hthb-countdown-wrap", 377 finalDate = $(countdown_id).data('countdown'), 378 customLabel = $(countdown_id).data('custom_label'); 379 $(countdown_id).countdown(finalDate, function (event) { 380 $(countdown_id+' .countdown-day').html(event.strftime('%D')); 381 $(countdown_id+' .countdown-day-text').html(customLabel.day); 382 $(countdown_id+' .countdown-hour').html(event.strftime('%H')); 383 $(countdown_id+' .countdown-hour-text').html(customLabel.hour); 384 $(countdown_id+' .countdown-minute').html(event.strftime('%M')); 385 $(countdown_id+' .countdown-minite-text').html(customLabel.min); 386 $(countdown_id+' .countdown-second').html(event.strftime('%S')); 387 $(countdown_id+' .countdown-second-text').html(customLabel.sec); 388 }); 389 }); 390 391 // Initialize new announcement bar countdowns 392 initializeNewAnnouncementBars(); 393 }); 394 395 /** 396 * Initialize new announcement bars with countdown timers 397 */ 398 function initializeNewAnnouncementBars() { 399 var bars = document.querySelectorAll('.hashbar-announcement-bar'); 400 if (bars.length === 0) { 401 return; 402 } 403
404 bars.forEach(function(bar) { 405 if (bar.getAttribute('data-countdown-enabled') === 'true') { 406 initializeCountdown(bar); 407 } 408 }); 409 } 410 411 /** 412 * Initialize countdown timer 413 */ 414 function initializeCountdown(bar) { 415 // Prevent multiple initializations on the same bar 416 if (bar.hasAttribute('data-countdown-initialized')) { 417 return; 418 } 419 bar.setAttribute('data-countdown-initialized', 'true'); 420 421 var countdownType = bar.getAttribute('data-countdown-type'); 422 var countdownDate = bar.getAttribute('data-countdown-date'); 423 424 // Find the bar wrapper (parent of the bar if it exists) 425 var barWrapper = bar.parentElement && bar.parentElement.classList.contains('hashbar-announcement-bar-wrapper') 426 ? bar.parentElement 427 : bar; 428 429 // Query all countdown timers in the wrapper (could be before, inline, after, or below) 430 var timerElements = barWrapper.querySelectorAll('.hashbar-countdown-timer-wrapper, .hashbar-countdown-timer-text'); 431 432 if (timerElements.length === 0 || !countdownDate) { 433 return; 434 } 435 436 // Copy color/label settings from bar to each timer element for use during rendering 437 var cdBgColor = bar.getAttribute('data-countdown-bg-color') || ''; 438 var cdTextColor = bar.getAttribute('data-countdown-text-color') || ''; 439 var cdLabelColor = bar.getAttribute('data-countdown-label-color') || ''; 440 var rawLabelDays = bar.getAttribute('data-countdown-label-days'); 441 var rawLabelHours = bar.getAttribute('data-countdown-label-hours'); 442 var rawLabelMinutes = bar.getAttribute('data-countdown-label-minutes'); 443 var rawLabelSeconds = bar.getAttribute('data-countdown-label-seconds'); 444 timerElements.forEach(function(timerEl) { 445 if (cdBgColor) timerEl.setAttribute('data-countdown-bg-color', cdBgColor); 446 if (cdTextColor) timerEl.setAttribute('data-countdown-text-color', cdTextColor); 447 if (cdLabelColor) timerEl.setAttribute('data-countdown-label-color', cdLabelColor); 448 // PHP sets style-specific defaults for new bars; '' means user explicitly cleared the label. 449 // Use !== null so '' (cleared) passes through rather than falling back to JS defaults. 450 var elStyle = timerEl.getAttribute('data-countdown-style') || 'simple'; 451 var defDays, defHours, defMins, defSecs; 452 if (elStyle === 'box' || elStyle === 'circular') { 453 defDays = 'Day'; defHours = 'Hour'; defMins = 'Minute'; defSecs = 'Second'; 454 } else if (elStyle === 'simple') { 455 defDays = 'd'; defHours = 'h'; defMins = 'm'; defSecs = 's'; 456 } else { 457 defDays = 'Days'; defHours = 'Hours'; defMins = 'Minutes'; defSecs = 'Seconds'; 458 } 459 timerEl.setAttribute('data-countdown-label-days', rawLabelDays !== null ? rawLabelDays : defDays); 460 timerEl.setAttribute('data-countdown-label-hours', rawLabelHours !== null ? rawLabelHours : defHours); 461 timerEl.setAttribute('data-countdown-label-minutes', rawLabelMinutes !== null ? rawLabelMinutes : defMins); 462 timerEl.setAttribute('data-countdown-label-seconds', rawLabelSeconds !== null ? rawLabelSeconds : defSecs); 463 if ((elStyle === 'simple' || elStyle === 'digital') && cdTextColor) { 464 timerEl.style.color = cdTextColor; 465 } 466 if (elStyle === 'digital' && cdBgColor) { 467 timerEl.style.backgroundColor = cdBgColor; 468 timerEl.style.padding = '4px 8px'; 469 timerEl.style.borderRadius = '4px'; 470 } 471 }); 472 473 // Expired action handler â runs once when the countdown reaches zero. 474 var expiredAction = bar.getAttribute('data-countdown-expired-action') || 'show_message'; 475 var expiredMessage = bar.getAttribute('data-countdown-expired-message') || ''; 476 var expiryHandled = false; 477 478 function handleExpiry() { 479 if (expiryHandled) return; 480 expiryHandled = true; 481 if (expiredAction === 'hide_bar') { 482 barWrapper.style.display = 'none'; 483 } else if (expiredAction === 'show_message') { 484 var safeMsg = expiredMessage 485 .replace(/&/g, '&') 486 .replace(/</g, '<') 487 .replace(/>/g, '>');
488 timerElements.forEach(function(el) { 489 el.innerHTML = '<span class="hashbar-countdown-expired-message">' + safeMsg + '</span>'; 490 }); 491 } 492 } 493 494 function updateAllTimers() { 495 var now = new Date().getTime(); 496 var countDate = new Date(countdownDate).getTime(); 497 var distance = countDate - now; 498 499 // Handle expiry before any DOM update â prevents flash of 00:00 for already-expired bars 500 if (distance < 0) { 501 handleExpiry(); 502 return; 503 } 504 505 timerElements.forEach(function(timerElement) { 506 updateCountdown(timerElement, countdownDate, countdownType); 507 }); 508 } 509 510 // Call synchronously on load so expired bars are hidden before first paint 511 updateAllTimers(); 512 var intervalId; 513 if (!expiryHandled) { 514 intervalId = setInterval(function() { 515 updateAllTimers(); 516 if (expiryHandled) clearInterval(intervalId); 517 }, 1000); 518 bar.setAttribute('data-countdown-interval', intervalId); 519 } 520 } 521 522 /** 523 * Update countdown display 524 */ 525 function updateCountdown(timerElement, countdownDate, countdownType) { 526 var now = new Date().getTime(); 527 var countDate = new Date(countdownDate).getTime(); 528 var distance = countDate - now; 529 530 if (distance < 0) { 531 return; 532 } 533 534 var days = Math.floor(distance / (1000 * 60 * 60 * 24)); 535 var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 536 var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); 537 var seconds = Math.floor((distance % (1000 * 60)) / 1000); 538 539 // Get display options from element attributes 540 var showDays = timerElement.getAttribute('data-show-days') !== 'false'; 541 var showHours = timerElement.getAttribute('data-show-hours') !== 'false'; 542 var showMinutes = timerElement.getAttribute('data-show-minutes') !== 'false'; 543 var showSeconds = timerElement.getAttribute('data-show-seconds') !== 'false'; 544 545 // Determine style (simple, digital, circular) 546 var style = timerElement.getAttribute('data-countdown-style') || 'simple'; 547 548 if (style === 'simple') { 549 // Simple text format using custom labels (no space â label acts as suffix) 550 var _lDays = timerElement.getAttribute('data-countdown-label-days'); 551 var _lHours = timerElement.getAttribute('data-countdown-label-hours'); 552 var _lMinutes = timerElement.getAttribute('data-countdown-label-minutes'); 553 var _lSeconds = timerElement.getAttribute('data-countdown-label-seconds'); 554 var lDays = _lDays !== null ? _lDays : 'd'; 555 var lHours = _lHours !== null ? _lHours : 'h'; 556 var lMinutes = _lMinutes !== null ? _lMinutes : 'm'; 557 var lSeconds = _lSeconds !== null ? _lSeconds : 's'; 558 var parts = []; 559 if (showDays && days > 0) parts.push(days + lDays); 560 if (showHours && hours > 0) parts.push(hours + lHours); 561 if (showMinutes && minutes > 0) parts.push(minutes + lMinutes); 562 if (showSeconds) parts.push(seconds + lSeconds); 563 564 timerElement.textContent = parts.length > 0 ? parts.join(' ') : '0' + lSeconds; 565 } else if (style === 'digital') { 566 // Digital format: "05:03:45:30" 567 var displayText = ''; 568 if (showDays) displayText += padZero(days) + ':'; 569 if (showHours) displayText += padZero(hours) + ':'; 570 if (showMinutes) displayText += padZero(minutes) + ':'; 571 if (showSeconds) displayText += padZero(seconds); 572 573 // Remove trailing colon if no seconds are shown 574 timerElement.textContent = displayText.replace(/:$/, ''); 575 } else if (style === 'circular' || style === 'box') { 576 // Circular or box format - update boxes 577 updateBoxCountdown(timerElement, days, hours, minutes, seconds, showDays, showHours, showMinutes, showSeconds); 578 } else if (countdownType === 'compact') { 579 // Legacy compact format 580 if (days > 0) { 581 timerElement.textContent = days + 'd ' + hours + 'h'; 582 } else if (hours > 0) { 583 timerElement.textContent = hours + 'h ' + minutes + 'm'; 584 } else { 585 timerElement.textContent = minutes + 'm ' + seconds + 's'; 586 } 587 } else { 588 // Legacy detailed format 589 timerElement.textContent = padZero(days) + ':' + padZero(hours) + ':' + padZero(minutes) + ':' + padZero(seconds); 590 } 591 } 592 593 /** 594 * Update box-style countdown display (circular or rounded squares) 595 */ 596 function updateBoxCountdown(timerElement, days, hours, minutes, seconds, showDays, showHours, showMinutes, showSeconds) { 597 var bgColor = timerElement.getAttribute('data-countdown-bg-color') || ''; 598 var textColor = timerElement.getAttribute('data-countdown-text-color') || ''; 599 var labelColor = timerElement.getAttribute('data-countdown-label-color') || ''; 600 var _rawDays = timerElement.getAttribute('data-countdown-label-days'); 601 var _rawHours = timerElement.getAttribute('data-countdown-label-hours'); 602 var _rawMins = timerElement.getAttribute('data-countdown-label-minutes'); 603 var _rawSecs = timerElement.getAttribute('data-countdown-label-seconds'); 604 var labelDays = _rawDays !== null ? _rawDays : 'Day'; 605 var labelHours = _rawHours !== null ? _rawHours : 'Hour'; 606 var labelMins = _rawMins !== null ? _rawMins : 'Minute';
607 var labelSecs = _rawSecs !== null ? _rawSecs : 'Second'; 608 609 function applyColors(numberEl, labelEl) { 610 if (textColor && numberEl) numberEl.style.color = textColor; 611 if (labelColor && labelEl) labelEl.style.color = labelColor; 612 if (bgColor && numberEl) { 613 var wrapper = numberEl.closest('.countdown-unit, .hb-countdown-unit, .countdown-circle-box, .countdown-box'); 614 if (wrapper) { 615 wrapper.style.backgroundColor = bgColor; 616 wrapper.style.borderColor = bgColor; 617 } 618 } 619 } 620 621 // Update days box (works with both .countdown-circle-box and .countdown-box classes) 622 if (showDays) { 623 var daysBox = timerElement.querySelector('.countdown-days'); 624 if (daysBox) { 625 daysBox.textContent = String(days).padStart(2, '0'); 626 } 627 var daysLabel = timerElement.querySelector('.countdown-days-label, .countdown-day-text'); 628 if (daysLabel && daysLabel.textContent !== labelDays) daysLabel.textContent = labelDays; 629 applyColors(daysBox, daysLabel); 630 } 631 632 // Update hours box 633 if (showHours) { 634 var hoursBox = timerElement.querySelector('.countdown-hours'); 635 if (hoursBox) { 636 hoursBox.textContent = String(hours).padStart(2, '0'); 637 } 638 var hoursLabel = timerElement.querySelector('.countdown-hours-label, .countdown-hour-text'); 639 if (hoursLabel && hoursLabel.textContent !== labelHours) hoursLabel.textContent = labelHours; 640 applyColors(hoursBox, hoursLabel); 641 } 642 643 // Update minutes box 644 if (showMinutes) { 645 var minutesBox = timerElement.querySelector('.countdown-minutes'); 646 if (minutesBox) { 647 minutesBox.textContent = String(minutes).padStart(2, '0'); 648 } 649 var minutesLabel = timerElement.querySelector('.countdown-minutes-label, .countdown-minute-text, .countdown-minite-text'); 650 if (minutesLabel && minutesLabel.textContent !== labelMins) minutesLabel.textContent = labelMins; 651 applyColors(minutesBox, minutesLabel); 652 } 653 654 // Update seconds box 655 if (showSeconds) { 656 var secondsBox = timerElement.querySelector('.countdown-seconds'); 657 if (secondsBox) { 658 secondsBox.textContent = String(seconds).padStart(2, '0'); 659 } 660 var secondsLabel = timerElement.querySelector('.countdown-seconds-label, .countdown-second-text'); 661 if (secondsLabel && secondsLabel.textContent !== labelSecs) secondsLabel.textContent = labelSecs; 662 applyColors(secondsBox, secondsLabel); 663 } 664 } 665 666 /** 667 * Pad number with leading zero 668 */ 669 function padZero(num) { 670 return (num < 10 ? '0' : '') + num; 671 } 672})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.