1document.addEventListener('DOMContentLoaded', function () { 2 /** 3 * Prevents clicks from triggering when dragging on carousel items, 4 * while still allowing click events when not dragging. 5 * 6 * @param {Element} viewport 7 */ 8 function attachDragClickGuard(viewport) { 9 let dragStartX = 0; 10 let isDragging = false; 11 let dragMoved = false; 12 13 viewport.addEventListener('mousedown', function (e) { 14 dragStartX = e.clientX; 15 isDragging = true; 16 dragMoved = false; 17 }); 18 19 viewport.addEventListener('mousemove', function (e) { 20 if (!isDragging) return; 21 if (!dragMoved && Math.abs(e.clientX - dragStartX) > 5) { 22 dragMoved = true; 23 } 24 }); 25 26 viewport.addEventListener('mouseup', function () { 27 isDragging = false; 28 }); 29 30 viewport.addEventListener('click', function (e) { 31 if (dragMoved) { 32 e.preventDefault(); 33 e.stopPropagation(); 34 dragMoved = false; 35 } 36 }, true); 37 } 38 39 // Defer carousel init to the next animation frame so all getComputedStyle / 40 // offsetWidth reads happen after the browser's first layout pass is committed, 41 // avoiding forced synchronous reflow on DOMContentLoaded. 42 requestAnimationFrame(function () { 43 if ('undefined' !== typeof TMBI_carousel) { 44 const rootStyles = getComputedStyle(document.documentElement); 45 const spacingSmRaw = rootStyles.getPropertyValue('--spacing-sm').trim(); 46 // --spacing-sm is always rem-based; convert to px using the root font-size. 47 const spacingSm = spacingSmRaw.endsWith('rem') 48 ? parseFloat(spacingSmRaw) * parseFloat(rootStyles.fontSize) 49 : parseFloat(spacingSmRaw); 50 51 TMBI_carousel.init('.homepage-carousel-wrapper', { 52 gap: spacingSm, 53 loop: true, 54 preview: true, 55 previewOffset: 0, 56 itemHeight: 600, 57 autoSlide: false, 58 itemWidth: 820, 59 progressBar: true, 60 eagerBoundarySlides: true, 61 responsive: { 62 0: { 63 items: 1, 64 swipe: 'vertical', 65 vertical: true, 66 preview: false, 67 itemHeight: 550, 68 }, 69 768: { 70 items: 1, 71 swipe: 'horizontal', 72 vertical: false, 73 preview: true, 74 itemWidth: 594, 75 itemHeight: 500, 76 }, 77 1025: { 78 items: 1, 79 swipe: 'horizontal', 80 vertical: false, 81 preview: true, 82 } 83 }, 84 }); 85 86 document.querySelectorAll('.homepage-carousel-wrapper').forEach(function (el) { 87 const track = el.querySelector('.carousel-track'); 88 const prevArrow = el.querySelector('.carousel-arrow.prev'); 89 90 if (track && prevArrow) { 91 track.addEventListener('transitionend', function onFirstAdvance(e) { 92 if (e.propertyName !== 'transform') { 93 return; 94 } 95 prevArrow.classList.remove('is-hidden'); 96 track.removeEventListener('transitionend', onFirstAdvance); 97 }); 98 } 99 100 const viewport = el.querySelector('.carousel-viewport'); 101 if (viewport) { 102 attachDragClickGuard(viewport); 103 } 104 }); 105 } 106 }); 107}); 108 109 110var tmbiContributorName = ''; 111 112document.addEventListener('click', function (event) { 113 var card = event.target.closest('.homepage-carousel-card'); 114 if (card) { 115 var contributorElement = card.querySelector('a[data-contributor-name]'); 116 tmbiContributorName = contributorElement ? contributorElement.dataset.contributorName : ''; 117 } 118}, true); 119 120wp.hooks.addFilter('tmbi_ga_custom_event_data_payload_filter', 'tmbi-generic-data-api', function (payload) { 121 payload['cd_author_name'] = tmbiContributorName || ''; 122 return payload; 123});
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.