1(function() { 2 //render promo banners into articles 3 const bannerRules = { 4 'zeit-magazin': [''], 5 'campus': [''], 6 'zett': [''], 7 'arbeit': [''], 8 'geld': [''], 9 'kultur': [''], 10 'digital': [''], 11 'gesellschaft': [''], 12 'politik': [''], 13 'wirtschaft': [''], 14 'sport': [''], 15 'wissen': [''], 16 'gesundheit': [''], 17 'familie':[''], 18 'sinn': [''], 19 'entdecken': [''] 20 }; 21 22 let bannerInjection; 23 24 if ( 25 window.Zeit.view.type && 26 window.Zeit.view.type === "article" && 27 window.location.href.indexOf("zeit.de/angebote") === -1 && 28 window.location.href.indexOf("zeit.de/campus/angebote") === -1 && 29 window.location.href.indexOf("zeit.de/zett/angebote") === -1 && 30 window.location.href.indexOf("zeit.de/arbeit/angebote") === -1 && 31 !document.querySelector(".article--visualarticle") 32 ) { 33 const executeIndividualArticleHacks = () => { 34 35 //START mama article hack 36 if ((window.location.href.indexOf("angriff-israel-hamas-kibbuz-reim-kinder") !== -1 || window.location.href.indexOf("attack-israel-hamas-kibbutz-reim-children-english") !== -1) && document.querySelector("#paywall")){ 37 function styleMamaArticle(){ 38 let css = '.paragraph--faded:before{background-image: linear-gradient(0deg, rgba(169, 168, 132, 1) 0%, rgba(169, 168, 132, 0) 100%);}@media (prefers-color-scheme:light){html:not(.color-scheme-dark) article.article{--z-color-link:#252525;--z-color-20:#252525;--z-color-30:#252525;--z-color-35:#252525;--z-color-45:#252525;--z-color-45--rgb:37,37,37;--z-color-60--beyond:#252525;--z-color-60:#252525;--z-color-70:#252525;--z-color-80:#252525;--z-color-90:#252525;--z-color-100:#fff;--z-color-link:#252525;--z-color-primary:#252525;--z-border-primary:#252525}html.color-scheme-light article.article .akzE:before,html.color-scheme-light article.article .akzN:before{color:#252525}}html.color-scheme-light article.article{--z-color-link:#252525;--z-color-20:#252525;--z-color-30:#252525;--z-color-35:#252525;--z-color-45:#252525;--z-color-45--rgb:37,37,37;--z-color-60--beyond:#252525;--z-color-60:#252525;--z-color-70:#252525;--z-color-80:#252525;--z-color-90:#252525;--z-color-100:#fff;--z-color-link:#252525;--z-color-primary:#252525;--z-border-primary:#252525}body.fullwidth-page .page__content{background-color:#A9A884}picture.header-fullwidth__media-container{display:none}.header-fullwidth__header{background-color:#A9A884}.header-fullwidth__header .header-fullwidth__overlay{color:#252525;text-shadow:none}.header-fullwidth__header .headline__supertitle,.header-fullwidth--classic .header-fullwidth__header:after,.header-fullwidth__overlay .header-fullwidth__arrow{display:none}.header-fullwidth__overlay .headline__title{font-size:16rem;line-height:100%;letter-spacing:0;font-family:"ZeitTiemannSchmal",Georgia,Palatino,"Palatino Linotype",FreeSerif,serif;font-weight:400;color:#fff}.header-fullwidth__overlay .zplus-logo{color:#fff!important}.header-fullwidth__copyright{display:none}.comment-section{background-color:#fff}@media screen and (max-width:768px){.header-fullwidth__overlay .headline__title{font-size:6rem;line-height:280%;letter-spacing:-2px}}'; 39 let styleTag = document.createElement('style'); 40 styleTag.innerHTML = css; 41 42 document.querySelector('head').appendChild(styleTag); 43 } 44 45 styleMamaArticle(); 46 } 47 //END mama article hack 48 } 49 50 executeIndividualArticleHacks(); 51 52 var pageElements = document.querySelectorAll(".article-page"); 53 54 if ( 55 window.Zeit.isMobileApp || 56 pageElements[0].getAttribute("data-page-number") == "1" 57 ) { 58 if ( 59 document.querySelectorAll(".article-body .paragraph").length > 3 60 ) { 61 checkBlacklistAndRender( 62 "https://static.zeit.de/embed/global-blacklist" 63 ); 64 } 65 } 66 } 67 68 function checkBlacklistAndRender(blacklistUrl) { 69 var httpRequest = new XMLHttpRequest(); 70 httpRequest.onreadystatechange = function() { 71 if (this.readyState == 4 && this.status == 200) { 72 var data = JSON.parse(httpRequest.responseText); 73 var currentURL = window.location.href; 74 var onBlacklist = data.urls.some(function(url) { 75 return currentURL.indexOf(url) !== -1; 76 }); 77 78 if (!onBlacklist && !hasEmbedAlready()) { 79 const wjwConfig = "https://static.zeit.de/pembeds/json/was-jetzt-config"; 80 async function getWJDWConfig(url) { 81 let response = await fetch(url); 82 let configData = await response.json(); 83 if (configData.hideWidget == 'nein') { 84 whichBanner(bannerRulesWJDW); 85 } else { 86 whichBanner(bannerRules); 87 } 88 } 89 getWJDWConfig(wjwConfig); 90 } 91 } 92 };
93 httpRequest.open("GET", blacklistUrl); 94 httpRequest.send(); 95 } 96 97 function buildContainerWJDW(elem){ 98 if (elem) { 99 var embedContainerSpeech = document.createElement("div"), 100 embedContainerPush = document.createElement("div"), 101 linkSpeech = "https://static.zeit.de/pembeds/was-jetzt-die-woche/wjw-sprachnachrichten-embed", 102 linkPush = "https://static.zeit.de/pembeds/was-jetzt-die-woche/wjw-push-embed"; 103 embedContainerSpeech.style.clear = "both"; 104 embedContainerPush.style.clear = "both"; 105 106 elem.after(embedContainerSpeech); 107 embedContainerSpeech.after(embedContainerPush); 108 109 renderDoubleWJDW(embedContainerSpeech, linkSpeech); 110 renderDoubleWJDW(embedContainerPush, linkPush); 111 } 112 } 113 114 function renderDoubleWJDW(container, url){ 115 if (container) { 116 async function getWJDWEmbed(url) { 117 let response = await fetch(url); 118 let embedHTML = await response.text(); 119 120 if (embedHTML) { 121 container.innerHTML = embedHTML; 122 123 var scriptTag = container.querySelector('script'), 124 scriptContent = scriptTag.innerHTML; 125 scriptTag.remove(); 126 127 var newTag = document.createElement('script'); 128 newTag.innerHTML = scriptContent; 129 130 document.querySelector('body').appendChild(newTag); 131 } 132 } 133 getWJDWEmbed(url); 134 } 135 } 136 137 function renderBanner(elem, url) { 138 if (elem) { 139 console.log(elem); 140 var embedContainer = document.createElement("div"); 141 embedContainer.style.clear = "both"; 142 embedContainer.classList.add('zoner-injection', 'zoner-injection-' + bannerInjection); 143 144 elem.after(embedContainer); 145 146 async function getEmbed(url) { 147 let response = await fetch(url); 148 let embedHTML = await response.text(); 149 150 if (embedHTML) { 151 embedContainer.innerHTML = embedHTML; 152 153 let scriptTags = embedContainer.querySelectorAll('script'); 154 155 scriptTags.forEach((scriptTag)=>{ 156 const scriptContent = scriptTag.innerHTML, 157 scriptSrc = scriptTag.src, 158 scriptType = scriptTag.getAttribute('type'); 159 160 scriptTag.remove(); 161 162 var newTag = document.createElement('script'); 163 newTag.innerHTML = scriptContent; 164 if (scriptSrc?.length > 0) { 165 newTag.src = scriptSrc; 166 } 167 newTag.setAttribute('type', scriptType ? scriptType : 'text/javascript'); 168 console.log(newTag); 169 170 document.querySelector('body').appendChild(newTag); 171 }) 172 173 let links = embedContainer.querySelectorAll('link'); 174 links.forEach((link)=>{ 175 document.querySelector('head').appendChild(link); 176 }) 177 178 let styles = embedContainer.querySelector('style'); 179 if (styles){ 180 document.querySelector('head').appendChild(styles); 181 } 182 } 183 } 184 getEmbed(url); 185 } 186 } 187 188 function whichBanner(rules){ 189 //find the banner types for this section 190 for (const [section, banners] of Object.entries(rules)) { 191 if (section == window.Zeit.view.ressort && banners) { 192 let banner; 193 //use probability to set which banner will be shown in the case that two are selected for this section 194 if (banners.length > 1) { 195 var diceThrow = Math.random(); 196 if (diceThrow < 0.5){ 197 banner = banners[0]; 198 } else { 199 banner = banners[1]; 200 } 201 } else { 202 banner = banners[0]; 203 } 204 205 bannerInjection = banner; 206 207 console.log('render ' + banner + ' banner into ' + section); 208 209 //render the chosen banner 210 switch (banner) { 211 case 'Z2X': 212 renderBanner(findGapForEmbed(), "https://static.zeit.de/embed/z2x25-ticket-einschuss"); 213 break; 214 case 'WJDW': 215 buildContainerWJDW(findGapForEmbed()); 216 break; 217 case 'AT': 218 renderBanner(findGapForEmbed(), "https://static.zeit.de/embed/ampeltelefon-einschuss"); 219 break; 220 case 'NSDAP': 221 renderBanner(findGapForEmbed(), "https://static.zeit.de/embed/nsdap-einschuss"); 222 break; 223 case 'CU': 224 renderBanner(findGapForEmbed(), "https://static.zeit.de/pembeds/umfrage-community-pembed"); 225 break; 226 case 'DUV': 227 if (!document.documentElement.dataset.isTruncatedByPaywall) { 228 renderBanner(findGapForEmbed(), "https://static.zeit.de/embed/duv-einschuss-250729"); 229 } 230 break; 231 } 232 } 233 } 234 } 235 236 //leaving the old embed classes in in case they are manually included
236somewhere 237 function hasEmbedAlready() { 238 if ( 239 document.querySelector( 240 'iframe[src^="https://app.mycountrytalks.org/"]' 241 ) || 242 document.querySelector(".zoner-injection") || 243 document.querySelector(".podfest-signup-wrapper") || 244 document.querySelector(".zoner-wjw-speech-wrapper") || 245 document.querySelector(".zoner-pland-survey") || 246 document.querySelector(".zoner-z2x24-einschuss-banner") 247 ) { 248 return true; 249 } else { 250 return false; 251 } 252 } 253 254 function findGapForEmbed() { 255 var articleWrapper = document.querySelector( 256 ".article-page[data-page-number='1']" 257 ); 258 259 if (articleWrapper) { 260 var articleElems = document.querySelectorAll(".article-page > *"); 261 var lengthCalc = 0; 262 for (var i = 0, len = articleElems.length; i < len; i++) { 263 if (articleElems[i].classList.contains("paragraph")) { 264 lengthCalc += articleElems[i].innerText.length; 265 266 if ( 267 articleElems[i + 1] !== undefined && 268 (articleElems[i + 1].classList.contains("paragraph") || 269 articleElems[i + 1].classList.contains( 270 "article__subheading" 271 )) && 272 lengthCalc > 1500 273 ) { 274 //if we place before the last para, it must be at least 200 characters long 275 if ( 276 i === len - 2 && 277 articleElems[len - 1].innerText.length >= 150 278 ) { 279 return articleElems[i]; 280 } 281 //if the paragraph is long enough and has a paragraph in front of it, it is viable 282 if ( 283 articleElems[i].innerText.length >= 150 && 284 articleElems[i - 1] !== undefined && 285 articleElems[i - 1].classList.contains("paragraph") 286 ) { 287 //if the paragraph after is long enough or has a para after it, it is viable 288 if ( 289 articleElems[i + 1] !== undefined && 290 (articleElems[i + 1].innerText.length >= 150 || 291 (articleElems[i + 2] !== undefined && 292 articleElems[i + 2].classList.contains( 293 "paragraph" 294 ))) 295 ) { 296 return articleElems[i]; 297 } else { 298 console.log('2: banner cannot be placed after'); 299 console.log(articleElems[i]); 300 } 301 } else { 302 console.log(articleElems[i].innerText.length); 303 console.log(articleElems[i - 1]); 304 } 305 } 306 } 307 } 308 } 309 } 310 //END generic banner einschuss logic 311})(); 312 313(function() { 314 // Article-Read-Tracking für ZAPP: postMessage sobald der Footer sichtbar wird 315 function trackArticleRead() { 316 if (!window.zappi || typeof window.zappi.postMessage !== 'function') return; 317 318 if (!('IntersectionObserver' in window)) return; 319 320 var footer = document.querySelector('div.article-footer'); 321 if (!footer) return; 322 323 function trackArticleFooterReached() { 324 // Abbruch, falls kein Browser-/DOM-Kontext (defensiv, z. B. SSR) 325 if (typeof window === "undefined" || typeof document === "undefined") 326 return; 327 328 var doc = document.documentElement; 329 var body = document.body || {}; 330 331 // Gescrollte Pixel (vertikal), cross-browser-defensiv 332 var pixelsScrolled = Math.round( 333 window.pageYOffset || doc.scrollTop || body.scrollTop || 0, 334 ); 335 336 // Gesamthöhe der Seite / WebView (gröÃter verfügbarer Wert) 337 var pageHeight = Math.round( 338 Math.max( 339 body.scrollHeight || 0, 340 body.offsetHeight || 0, 341 doc.clientHeight || 0, 342 doc.scrollHeight || 0, 343 doc.offsetHeight || 0, 344 ), 345 ); 346 347 window.dataLayer = window.dataLayer || []; 348 window.dataLayer.push({ 349 event: "click", 350 tracking_info: { 351 linkId: "#article-footer-reached", 352 customClickParameter: { 353 6: pixelsScrolled, 354 7: pageHeight, 355 8: "footer_reached", 356 9: "article", 357 }, 358 sendOnUnload: 1, 359 }, 360 }); 361 } 362 363 function fireRead() { 364 try { 365 window.zappi.postMessage({ 366 type: 'article-interaction', 367 action: 'read' 368 }); 369 } catch (e) { 370 // absichtlich verschluckt 371 } 372 } 373 374 try { 375 var observer = new IntersectionObserver(function(entries) {
376 entries.forEach(function(entry) { 377 if (entry.isIntersecting) { 378 fireRead(); 379 trackArticleFooterReached(); 380 observer.disconnect(); // nur einmal feuern 381 } 382 }); 383 }); 384 observer.observe(footer); 385 } catch (e) { 386 // defensiv 387 } 388 } 389 390 if (document.readyState === 'loading') { 391 document.addEventListener('DOMContentLoaded', trackArticleRead); 392 } else { 393 trackArticleRead(); 394 } 395})();
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.