1/** 2 * Frontend JavaScript for PYMNTS News & Trends Ad Configuration 3 */ 4(function() { 5 'use strict'; 6 7 // Get placement settings from WordPress 8 const placementSettings = window.pymntsAdPlacementSettings || { 9 ads_enabled: false, 10 dianomi_context_id: '4673', 11 placement_mode: 'interval', 12 first_ad_after_posts: 2, 13 ad_interval: 2, 14 total_ads: 3, 15 ad_positions: [2, 5, 8] 16 }; 17 18 /** 19 * Ad Placement Manager 20 */ 21 const AdPlacementManager = { 22 /** 23 * Insert ad HTML 24 */ 25 insertAd: function(adIndex) { 26 // The container is empty until contextfeed.js fills it, so the slot 27 // sits blank between two posts. Shaped like the feed rows around 28 // it: a 160x90 thumbnail, then eyebrow, headline, excerpt and date. 29 // aria-hidden: it stands in for sponsored content and conveys 30 // nothing worth announcing. dianomi-skeleton.js removes it. 31 const skeleton = '<div class="pymnts-ad-skeleton pymnts-ad-skeleton--feed" aria-hidden="true">' 32 + '<div class="pymnts-ad-skeleton__media"></div>' 33 + '<div class="pymnts-ad-skeleton__body">' 34 + '<div class="pymnts-ad-skeleton__line pymnts-ad-skeleton__line--label"></div>' 35 + '<div class="pymnts-ad-skeleton__line"></div>' 36 + '<div class="pymnts-ad-skeleton__line pymnts-ad-skeleton__line--short"></div>' 37 + '<div class="pymnts-ad-skeleton__line pymnts-ad-skeleton__line--label"></div>' 38 + '</div>' 39 + '</div>'; 40 41 // mb-3 matches the feed rows, so the slot keeps their rhythm instead 42 // of sitting flush against the post underneath it. 43 return `<div class="dianomi_context pymnts-ad--feed mb-3 mt-0" data-dianomi-context-id="${placementSettings.dianomi_context_id}" id="dianomi-ad-${adIndex}">${skeleton}</div>`; 44 }, 45 46 /** 47 * Check if ad should be shown at position (positions mode) 48 */ 49 shouldShowAdAtPosition: function(position) { 50 return placementSettings.ad_positions && 51 Array.isArray(placementSettings.ad_positions) && 52 placementSettings.ad_positions.includes(position); 53 }, 54 55 /** 56 * Check if ad should be shown after post (interval mode) 57 */ 58 shouldShowAdAfterPost: function(postPosition) { 59 return postPosition === placementSettings.first_ad_after_posts || 60 (postPosition > placementSettings.first_ad_after_posts && 61 (postPosition - placementSettings.first_ad_after_posts) % placementSettings.ad_interval === 0); 62 }, 63 64 /** 65 * Process posts array and return HTML with ads inserted 66 * This function takes the posts array and returns complete HTML with ads inserted 67 */ 68 processPosts: function(posts, postHtmlCallback) { 69 if (!placementSettings.ads_enabled) { 70 return posts.map(postHtmlCallback).join(''); 71 } 72 73 let adIndex = 0; 74 let visualPosition = 0; 75 let html = ''; 76 77 posts.forEach(function(post, index) { 78 // Render post 79 visualPosition++; 80 html += postHtmlCallback(post); 81 82 // Insert ad based on placement mode 83 if (placementSettings.placement_mode === 'positions') { 84 if (AdPlacementManager.shouldShowAdAtPosition(visualPosition + 1)) { 85 visualPosition++; 86 adIndex++; 87 html += AdPlacementManager.insertAd(adIndex); 88 } 89 } else if (placementSettings.placement_mode === 'interval') { 90 if (AdPlacementManager.shouldShowAdAfterPost(index + 1)) { 91 adIndex++; 92 html += AdPlacementManager.insertAd(adIndex); 93 } 94 } 95 }); 96 97 return html; 98 }, 99 100 /** 101 * Initialize Dianomi ads 102 */ 103 initializeDianomiAds: function(container) { 104 const adContainers = container.querySelectorAll('.dianomi_context'); 105 106 // ?pymnts_ads_skeleton=1 holds the placeholders instead of the ads. 107 if (adContainers.length === 0 || window.pymntsAdsHoldSkeleton) { 108 return; 109 } 110 111 // These slots are injected after page load, so the shared watcher 112 // has already scanned without seeing them. 113 if (window.pymntsDianomiSkeleton) { 114 window.pymntsDianomiSkeleton.scan(container); 115 } 116 117 // Hands the slots to the ads plugin's loader, which fetches the 118 // vendor script when one nears the viewport. Injecting that script 119 // here instead loaded it eagerly for every Dianomi slot on the page. 120 if (window.pymntsDianomiLazy) { 121 window.pymntsDianomiLazy.scan(container); 122 } 123 } 124 }; 125 126 // Expose AdPlacementManager globally for use in theme 127 window.PYMNTSAdPlacementManager = AdPlacementManager; 128})(); 129
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.