1var elem = document.getElementById('infinite-article-analytics'); 2var article_legacy_url = elem.getAttribute('article_legacy_url'); 3var publive_analytics = elem.getAttribute('publive_analytics'); 4let already_visited = article_legacy_url 5var first_article_url = article_legacy_url 6var previousPageURL = article_legacy_url 7const page_visited={} 8 9class UniqueQueue { 10 constructor() { 11 this.queue = []; 12 this.elements = new Set(); 13 } 14 15 _serialize(item) { 16 return JSON.stringify(item); 17 } 18 19 enqueue(item) { 20 const itemStr = this._serialize(item); 21 if (!this.elements.has(itemStr)) { 22 this.queue.push(item); 23 this.elements.add(itemStr); 24 } else { 25 } 26 } 27 28 dequeue() { 29 if (this.queue.length > 0) { 30 const item = this.queue.shift(); 31 this.elements.delete(this._serialize(item)); 32 return item; 33 } else { 34 return null; 35 } 36 } 37 38 peek() { 39 if (this.queue.length > 0) { 40 return this.queue[0]; 41 } else { 42 return null; 43 } 44 } 45 length() { 46 if (this.queue.length > 0) { 47 return this.queue.length; 48 } else { 49 return null; 50 } 51 } 52 53 isEmpty() { 54 return this.queue.length === 0; 55 } 56 57 size() { 58 return this.queue.length; 59 } 60 61 logAndDequeue() { 62 const item = this.dequeue(); 63 if (item !== null) { 64 return item 65 } 66 return null 67 } 68 } 69 70 const uniqueQueue = new UniqueQueue(); 71 72 73 // Helper function to get data attributes 74function getDataAttributes(element, attrs) { 75 return attrs.reduce((acc, attr) => { 76 acc[attr] = element.dataset[attr]; 77 return acc; 78 }, {}); 79} 80 81// Check if an element is in a certain height for analytics 82function isInCertainHeightForAnalytics(element) { 83 const elementTop = element?.getBoundingClientRect()?.top + window.scrollY; 84 const viewportTop = window.scrollY + 100; 85 const viewportBottomNew = viewportTop + window.innerHeight - 700; 86 return (viewportTop < elementTop && elementTop < viewportBottomNew); 87} 88 89// Log and dequeue at intervals 90function logAndDequeueInterval() { 91 setInterval(() => { 92 const currentVisitedArticle = uniqueQueue.logAndDequeue(); 93 if (currentVisitedArticle) { 94 try { 95 const element = document.querySelector(currentVisitedArticle); 96 const eventData = getDataAttributes(element, [ 97 'pageTitle', 'pagePrimaryCategory', 'pageAuthor', 98 'pagePostId', 'pagePublisherId', 'pageLangCode', 99 'pagePublisherDomain', 'pageUrl' 100 ]); 101 eventData.referenceUrl = previousPageURL; 102 eventData.utm_medium = 'infinite-scroll'; 103 trackAnalyticsEvent('page_view', eventData); 104 if (first_article_url) { 105 first_article_url = undefined; 106 } 107 } catch (error) { 108 console.log('Error in analytics', error); 109 } 110 previousPageURL = document.querySelector(currentVisitedArticle).dataset.pageUrl; 111 } 112 }, 2000); // trigger analytics event every 2 seconds 113} 114 115try { 116 if (publive_analytics) { 117 logAndDequeueInterval(); 118 } 119} catch (error) { 120 console.log('error in fetching infinite scroll analytics data', error); 121} 122 123// Handle resize and scroll events 124window.addEventListener('resize', handleScrollResize); 125 126function throttle(func, limit) { 127 let inThrottle; 128 return function() { 129 const context = this; 130 const args = arguments; 131 if (!inThrottle) { 132 func.apply(context, args); 133 inThrottle = true; 134 setTimeout(() => inThrottle = false, limit); 135 } 136 } 137} 138const throttledScroll = throttle(handleScrollResize, 200); // Throttle to 200ms 139window.addEventListener('scroll', throttledScroll); 140 141// Check if window.visited_pages is not defined or is not an array 142if (!window.visited_pages || !Array.isArray(window.visited_pages)) { 143 window.visited_pages = []; // Initialize it as an empty array 144} 145 146 147function handleScrollResize() { 148 try { 149 if (publive_analytics) { 150 // const url = article_url_string(); 151 for (let i = 0; i < window.visited_pages.length; i++) { 152 const articleElement = document.querySelector('.article_scroll_post_' + window.visited_pages[i]); 153 if (isInCertainHeightForAnalytics(articleElement)) { 154 const url = articleElement.dataset.pageUrl; 155 if (first_article_url !== url && (already_visited && already_visited !== url)) { 156 already_visited = url; 157 setTimeout(() => { 158 uniqueQueue.enqueue('.article_scroll_post_' + window.visited_pages[i]); 159 }, 2000); 160 } 161 } 162 } 163 } 164 } catch (err) { 165 console.log('error in resize scroll', err); 166 } 167}
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.