1import Page from '../page.js' 2import Util from '../../util/util.js'; 3 4export default class SSEArticleDetail extends Page { 5 6 7 constructor() { 8 super(); 9 this.$lokedModal = document.getElementById('locked-modal'); 10 this.$lockedModalClose = this.$lokedModal.querySelector('.close-btn'); 11 document.getElementById('nav').classList.add('dark'); 12 document.getElementById('search').classList.add('dark'); 13 this.setTheme('light'); 14 this.checkForArticleLimit(); 15 this.initRecommendedArticleTracking(); 16 this.initDownloadArticleTracking(); 17 this.initShareArticleTracking(); 18 } 19 20 paralax(data) { 21 super.paralax(data); 22 } 23 24 initIntro() { 25 super.initIntro(); 26 } 27 28 intro() { 29 super.intro(); 30 } 31 32 /** 33 * Verifies if the content 34 */ 35 36 37 checkForArticleLimit() { 38 if (drupalSettings?.gssiBlocks?.article?.locked) { 39 this.$lokedModal.classList.add('show'); 40 window.lenisScroll.stop(); 41 this.$lockedModalClose.addEventListener('click', () => { 42 location.href = '/sports-science-exchange'; 43 }); 44 } 45 } 46 47 initRecommendedArticleTracking() { 48 const recommendedCards = document.querySelectorAll('#related-cards .card-main'); 49 recommendedCards.forEach($card => { 50 const title = $card.querySelector('.card-main-content strong').textContent.trim(); 51 const topic = $card.dataset.category || $card.querySelector('.card-main-info span')?.textContent?.trim() || 'Sin categorÃa'; 52 53 $card.addEventListener('click', (e) => { 54 const el = e.currentTarget; 55 const href = el.querySelector('a')?.getAttribute('href') || el.getAttribute('href'); 56 // Note: card-main usually wraps content but might not be the anchor itself depending on markup. 57 // Browsing sse/article-detail.js: line 47: const recommendedCards = document.querySelectorAll('#related-cards .card-main'); 58 // line 52: $card.addEventListener('click', ... 59 // If card-main is an <a> tag (like in previous files), getAttribute('href') works. 60 // Let's assume consistent structure with other pages where card-main IS the trigger. 61 // Wait, earlier files used `.card-main` which was an `<a>`. 62 // Let's verify if `card-main` is `a` or `div`. 63 // In sse/index.html.twig line 72: <a class="card-main" ... 64 // So yes, it is an anchor. 65 66 const isNewTab = el.target === '_blank' || e.metaKey || e.ctrlKey || e.shiftKey; 67 const shouldRedirect = !isNewTab && href && href !== '#' && !href.startsWith('javascript:'); 68 69 const userStatus = (drupalSettings && drupalSettings.user && drupalSettings.user.uid && drupalSettings.user.uid !== 0) ? 'Registrado' : 'Invitado'; 70 71 const payload = { 72 event: "recommended_article", 73 article_name: title, 74 topic_name: [Util.toSentenceCase(topic)], 75 section_name: Util.toSentenceCase("Sports Science Exchange"), 76 status: userStatus 77 }; 78 79 if (shouldRedirect) { 80 e.preventDefault(); 81 e.stopPropagation(); 82 if (typeof window.handleLinkDelay === 'function') { 83 window.handleLinkDelay(e, payload, href); 84 } else { 85 if (typeof window.triggerDataLayerPush === 'function') { 86 window.triggerDataLayerPush(payload); 87 } 88 setTimeout(() => { window.location.href = href; }, 500); 89 } 90 } else { 91 if (typeof window.triggerDataLayerPush === 'function') { 92 window.triggerDataLayerPush(payload); 93 } 94 } 95 }); 96 }); 97 } 98 99 trackRecommendedArticleView(title, topic) { 100 const userStatus = (drupalSettings && drupalSettings.user && drupalSettings.user.uid && drupalSettings.user.uid !== 0) ? 'Registrado' : 'Invitado'; 101 if (typeof window.triggerDataLayerPush === 'function') { 102 window.triggerDataLayerPush({ 103 event: "recommended_article", 104 article_name: title, 105 topic_name: [Util.toSentenceCase(topic)], 106 section_name: Util.toSentenceCase("Sports Science Exchange"), 107 status: userStatus 108 }); 109 } 110 } 111 112 initDownloadArticleTracking() { 113 const $downloadButton = document.querySelector('.download-article a'); 114 if ($downloadButton) { 115 $downloadButton.addEventListener('click', () => { 116 this.trackDownloadArticle(); 117 }); 118 } 119 } 120 121 trackDownloadArticle() { 122 const title = document.querySelector('h1.smart-text').textContent.trim(); 123 const topic = document.querySelector('.hero-with-media-content small')?.textContent?.trim() || 'Sin categorÃa'; 124 const userStatus = (drupalSettings && drupalSettings.user && drupalSettings.user.uid && drupalSettings.user.uid !== 0) ? 'Registrado' : 'Invitado'; 125 126 if (typeof window.triggerDataLayerPush === 'function') { 127 window.triggerDataLayerPush({ 128 event: "download_article", 129 article_name: title, 130 topic_name: [Util.toSentenceCase(topic)], 131 section_name: Util.toSentenceCase("Sports Science Exchange"), 132 status: userStatus 133 }); 134 } 135 } 136 137 initShareArticleTracking() { 138 const shareButtons = document.querySelectorAll('[data-share]'); 139 shareButtons.forEach(button => { 140 button.addEventListener('click', () => { 141 const isTop = button.closest('.hero-with-media-bottom-right'); 142 const position = isTop ? 'Botón superior' : 'Botón inferior';
143 this.trackShareArticle(position); 144 }); 145 }); 146 } 147 148 trackShareArticle(position) { 149 const title = document.querySelector('h1.smart-text').textContent.trim(); 150 const topic = document.querySelector('.hero-with-media-content small')?.textContent?.trim() || 'Sin categorÃa'; 151 const userStatus = (drupalSettings && drupalSettings.user && drupalSettings.user.uid && drupalSettings.user.uid !== 0) ? 'Registrado' : 'Invitado'; 152 153 if (typeof window.triggerDataLayerPush === 'function') { 154 window.triggerDataLayerPush({ 155 event: "share_article", 156 article_name: title, 157 topic_name: [Util.toSentenceCase(topic)], 158 section_name: Util.toSentenceCase("Sports Science Exchange"), 159 status: userStatus, 160 social: "WhatsApp", 161 position: position 162 }); 163 } 164 } 165} 166new SSEArticleDetail(); 167window.addEventListener("pageshow", function (event) { 168 if (event.persisted) { 169 location.reload(); 170 } 171});
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.