1var isIE11 = !!window.MSInputMethodContext && !!document.documentMode; 2(function addTransitionsAfterLoad() { 3 var page = document.querySelector(".page"); 4 document.addEventListener("DOMContentLoaded", function () { 5 page.classList.remove("not-loaded"); 6 }); 7})(); 8 9if (!SVGElement.prototype.contains) 10 SVGElement.prototype.contains = HTMLDivElement.prototype.contains; 11 12function is_touch_enabled() { 13 return ( 14 "ontouchstart" in window || 15 navigator.maxTouchPoints > 0 || 16 navigator.msMaxTouchPoints > 0 17 ); 18} 19 20(function () { 21 if (typeof window.CustomEvent === "function") return false; //If not IE 22 23 function CustomEvent(event, params) { 24 params = params || { 25 bubbles: false, 26 cancelable: false, 27 detail: undefined, 28 }; 29 var evt = document.createEvent("CustomEvent"); 30 evt.initCustomEvent( 31 event, 32 params.bubbles, 33 params.cancelable, 34 params.detail 35 ); 36 return evt; 37 } 38 39 CustomEvent.prototype = window.Event.prototype; 40 41 window.CustomEvent = CustomEvent; 42})(); 43 44// https://tc39.github.io/ecma262/#sec-array.prototype.includes 45if (!Array.prototype.includes) { 46 Object.defineProperty(Array.prototype, "includes", { 47 value: function (searchElement, fromIndex) { 48 if (this == null) { 49 throw new TypeError('"this" is null or not defined'); 50 } 51 52 // 1. Let O be ? ToObject(this value). 53 var o = Object(this); 54 55 // 2. Let len be ? ToLength(? Get(O, "length")). 56 var len = o.length >>> 0; 57 58 // 3. If len is 0, return false. 59 if (len === 0) { 60 return false; 61 } 62 63 // 4. Let n be ? ToInteger(fromIndex). 64 // (If fromIndex is undefined, this step produces the value 0.) 65 var n = fromIndex | 0; 66 67 // 5. If n ⥠0, then 68 // a. Let k be n. 69 // 6. Else n < 0, 70 // a. Let k be len + n. 71 // b. If k < 0, let k be 0. 72 var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); 73 74 function sameValueZero(x, y) { 75 return ( 76 x === y || 77 (typeof x === "number" && 78 typeof y === "number" && 79 isNaN(x) && 80 isNaN(y)) 81 ); 82 } 83 84 // 7. Repeat, while k < len 85 while (k < len) { 86 // a. Let elementK be the result of ? Get(O, ! ToString(k)). 87 // b. If SameValueZero(searchElement, elementK) is true, return true. 88 if (sameValueZero(o[k], searchElement)) { 89 return true; 90 } 91 // c. Increase k by 1. 92 k++; 93 } 94 95 // 8. Return false 96 return false; 97 }, 98 }); 99} 100 101var language = document.documentElement.getAttribute("lang"); 102var hyphenate; 103var langSupported = false; 104switch (language) { 105 case "en_GB": 106 hyphenate = createHyphenator(hyphenationPatternsEnGb); 107 langSupported = true; 108 break; 109 case "de_DE": 110 langSupported = true; 111 hyphenate = createHyphenator(hyphenationPatternsDe); 112 break; 113} 114(function addShies() { 115 if (langSupported) { 116 var headlines = document.querySelectorAll( 117 "h1, h2, h3, .button--hollow, .markets .widget .bottom .title, .report__title, .news-teaser__link, .profit-tile .title" 118 ); 119 for (var i = 0, len = headlines.length; i < len; i++) { 120 var headline = headlines[i]; 121 if (headline.classList[0]) { 122 if (headline.classList[0].indexOf("headline") !== -1) continue; 123 } 124 if (!headline.children.length) { 125 var pieces = headline.innerHTML.split(" "); 126 pieces.forEach(function (piece, index) { 127 var charsOnly = piece.match(/\S+/g); 128 if (!charsOnly) return; 129 if (charsOnly[0].length > 15) { 130 pieces[index] = hyphenate(piece); 131 headline.innerHTML = pieces.join(" "); 132 } 133 }); 134 } 135 } 136 } 137})(); 138
139(function dienstePlusButton() { 140 svg = 141 '<svg xmlns="http://www.w3.org/2000/svg" width="898" height="139" viewBox="0 0 69297 10715" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"><path d="M39032 3h20823c946 0 1419 486 1419 1457v3537c0 887-482 1487-1399 1487H38971c-917 0-1399-600-1399-1487V1460c0-972 473-1457 1419-1457h42z" fill="#004263"/><path fill="#eb4245" d="M57707 1382h387v1667h-387z"/><path fill="#ffa200" d="M56040 3436v-387h1667v387z"/><path fill="#47c2ee" d="M59762 3049v387h-1668v-387z"/><path fill="#bace15" d="M57707 3436h387v1668h-387z"/><path d="M42041 4041c0 207-56 373-167 496s-269 185-473 185h-1507V1757h1498c433 0 649 222 649 667v1618zm-427-138V2538c0-234-119-351-356-351h-934v2103h934c237 0 356-129 356-387zm1361 818h-431V1756h431v2965zm2428 0h-1231c-213 0-379-52-498-156-130-110-196-268-196-476V2413c0-205 58-365 173-482 116-117 276-175 480-175h1271v431h-1120c-249 0-373 111-373 333v507h1494v427h-1494v498c0 225 126 338 378 338h1116v431zm2605-369c0 113-30 206-89 280-65 83-153 124-262 124-104 0-184-33-240-98-24-27-67-107-129-240l-1005-2102v2405h-413V2165c0-290 117-436 351-436 107 0 188 31 245 93 30 33 74 113 133 240l996 2098V1755h413v2596zm2384-2165h-1104c-180 0-292 46-336 138-27 53-40 179-40 378 0 104 34 184 102 240 56 44 148 67 276 67h458c196 0 352 53 469 160s176 256 176 449v471c0 204-60 361-181 469-120 108-284 162-492 162h-1239v-431h1110c184 0 299-50 344-151 21-48 31-179 31-396 0-202-120-302-360-302h-458c-190 0-345-50-467-151-133-110-200-258-200-445v-462c0-210 73-376 217-498 101-86 247-129 439-129h1255v431zm2271 0h-738v2534h-431V2187h-733v-431h1902v431zm2219 2534h-1231c-213 0-379-52-498-156-130-110-196-268-196-476V2413c0-205 58-365 173-482 116-117 276-175 480-175h1271v431h-1120c-249 0-373 111-373 333v507h1494v427h-1494v498c0 225 126 338 378 338h1116v431z" fill="#fefefe" fill-rule="nonzero"/><path fill="#fff001" d="M0 9813h7700v902H0z"/><path fill="#ffa200" d="M7700 9813h7700v902H7700z"/><path fill="#f96400" d="M15399 9813h7700v902h-7700z"/><path fill="#f62b2f" d="M23099 9813h7700v902h-7700z"/><path fill="#fa75ac" d="M30799 9813h7700v902h-7700z"/><path fill="#47c2ee" d="M38499 9813h7700v902h-7700z"/><path fill="#15b2b7" d="M46198 9813h7700v902h-7700z"/><path fill="#40a907" d="M53898 9813h7700v902h-7700z"/><path fill="#b8d000" d="M61598 9813h7700v902h-7700z"/><path d="M8975 1407c0-99 9-198 27-288C9119 381 9569 3 10325 3h2880v1395h-2511c-36 9-63 9-90 27-144 54-234 189-234 387v720h1951v1395h-1951v720c0 306 99 414 360 441h2475v1395h-2682c-1044 0-1548-486-1548-1350V1407zM14227 3h1395v4824c27 180 153 261 477 261h945c324 0 450-81 468-243l9-45V3h1395v4860c0 513-36 693-144 909-261 495-648 711-1305 711h-1791c-657 0-1053-216-1305-702-108-216-144-396-144-909V2zm14157 0h1416v6480h-1416V3zm7450 5292c-99 783-540 1188-1323 1188h-3366V3h3312c877 0 1328 388 1388 1229l-5 4012c-2 17 2-18 5-52m-1874-103c369 0 450-81 477-468 9-27 9-63 9-90V1696c-36-180-117-252-387-288-36-9-71-9-108-9h-1422v3690h1431zM25608 1v4657c-29 362-118 442-478 442h-839V1188h-1423l-1 3471c-29 362-118 442-478 442h-854V5h-1389v5292c0 818 530 1176 1295 1186v5l4251-3v-3c740-30 1333-427 1333-1185 0-163 5-5295 5-5295h-1423z" fill="#004263" fill-rule="nonzero"/></svg>'; 142 var targets = document.querySelectorAll(".button--services"); 143 for (var i = 0, len = targets.length; i < len; i++) { 144 target = targets[i]; 145 target.innerHTML = svg; 146 } 147})(); 148 149(function powerBreadcrumb() { 150 var target1 = document.querySelector(".hero--1"); 151 var target2 = document.querySelector(".section-grey--power"); 152 var target3 = document.querySelector(".market-nav"); 153 var target4 = document.querySelector(".behind-breadcrumb"); 154 if (target1 || target4) { 155 var heroSection = document.querySelector(".hero-section"); 156 heroSection.classList.add("hero-section--power-breadcrumb"); 157 } 158 if (target2) { 159 var heroSection = document.querySelector(".hero-section"); 160 heroSection.classList.add("hero-section--power-breadcrumb"); 161 heroSection.classList.add("hero-section--power-breadcrumb-grey"); 162 document.body.classList.add("grey__header"); 163 } 164 if (target3) { 165 var heroSection = document.querySelector(".hero-section"); 166 heroSection.classList.add("hero-section--power-breadcrumb"); 167 heroSection.classList.add("hero-section--power-breadcrumb-grey"); 168 document.body.classList.add("hero__overlay"); 169 document.body.classList.add("grey__header"); 170 } 171})(); 172 173function closestByClass(el, elClass) { 174 while ( 175 typeof el !== "undefined" && 176 typeof el.classList !== "undefined" && 177 !el.classList.contains(elClass) 178 ) { 179 el = el.parentNode; 180 if (!el) { 181 return false;
182 } 183 } 184 return el; 185} 186 187(function cropTeaserTexts() { 188 function cropArticle(article, words) { 189 if (!article.text) { 190 article.text = article.innerHTML; 191 } 192 var text = article.text; 193 text = text.split(" "); 194 195 var newText = ""; 196 for (var i = 0, len = text.length; i < len; i++) { 197 var word = text[i]; 198 if (i <= words) { 199 newText += word + " "; 200 } 201 } 202 203 if (text.length > words) { 204 newText += "..."; 205 } 206 article.innerHTML = newText; 207 } 208 209 var articles = document.querySelectorAll(".news-detail .article"); 210 211 if (articles) { 212 function crop() { 213 var wordAmmount; 214 window.innerWidth > 991 ? (wordAmmount = 10) : (wordAmmount = 14); 215 for (var i = 0, len = articles.length; i < len; i++) { 216 var article = articles[i]; 217 cropArticle(article, wordAmmount); 218 } 219 } 220 221 crop(); 222 223 window.addEventListener("resize", function () { 224 crop(); 225 }); 226 } 227})(); 228 229var styledSelects = (function () { 230 var selects = document.querySelectorAll( 231 ".select, .frame-type-form_formframework select:not(.xlarge), .tx-euwid-search select" 232 ); 233 234 function initSelect(select, borderless) { 235 select.choices = new Choices(select, { 236 silent: false, 237 items: [], 238 choices: [], 239 renderChoiceLimit: -1, 240 maxItemCount: -1, 241 addItems: true, 242 addItemFilterFn: null, 243 removeItems: true,
244 removeItemButton: false, 245 editItems: false, 246 duplicateItemsAllowed: true, 247 delimiter: ",", 248 paste: true, 249 searchEnabled: false, 250 searchChoices: true, 251 searchFloor: 1, 252 searchResultLimit: 4, 253 searchFields: ["label", "value"], 254 position: "auto", 255 resetScrollPosition: true, 256 shouldSort: false, 257 shouldSortItems: false, 258 placeholder: true, 259 placeholderValue: null, 260 searchPlaceholderValue: null, 261 prependValue: null, 262 appendValue: null, 263 renderSelectedChoices: "auto", 264 loadingText: "Loading...", 265 noResultsText: "No results found", 266 noChoicesText: "No choices to choose from", 267 itemSelectText: "", 268 addItemText: function (value) { 269 return 'Press Enter to add <b>"' + value + '"</b>'; 270 }, 271 maxItemText: function (maxItemCount) { 272 return "Only " + maxItemCount + " values can be added"; 273 }, 274 itemComparer: function (choice, item) { 275 return choice === item; 276 }, 277 classNames: { 278 containerOuter: borderless 279 ? "choices choices--borderless" 280 : "choices", 281 containerInner: "choices__inner", 282 input: "choices__input", 283 inputCloned: "choices__input--cloned", 284 list: "choices__list", 285 listItems: "choices__list--multiple", 286 listSingle: "choices__list--single", 287 listDropdown: "choices__list--dropdown", 288 item: "choices__item", 289 itemSelectable: "choices__item--selectable", 290 itemDisabled: "choices__item--disabled", 291 itemChoice: "choices__item--choice", 292 placeholder: "choices__placeholder", 293 group: "choices__group", 294 groupHeading: "choices__heading", 295 button: "choices__button", 296 activeState: "is-active", 297 focusState: "is-focused", 298 openState: "is-open", 299 disabledState: "is-disabled", 300 highlightedState: "is-highlighted", 301 hiddenState: "is-hidden", 302 flippedState: "is-flipped", 303 loadingState: "is-loading", 304 noResults: "has-no-results", 305 noChoices: "has-no-choices", 306 }, 307 // Choices uses the great Fuse library for searching. You 308 // can find more options here: https://github.com/krisk/Fuse#options 309 fuseOptions: { 310 include: "score", 311 }, 312 callbackOnInit: null, 313 callbackOnCreateTemplates: null, 314 }); 315 } 316 317 if (selects.length === 0) { 318 return; 319 } 320 321 function init() { 322 selects = document.querySelectorAll( 323 ".select, .frame-type-form_formframework select:not(.xlarge), .tx-euwid-search select" 324 ); 325 for (var i = 0, len = selects.length; i < len; i++) { 326 var select = selects[i]; 327 if (!select.choices) { 328 initSelect( 329 select, 330 classListContainsClass( 331 select.classList, 332 "select--borderless" 333 ) 334 ); 335 } 336 } 337 338 (function addIndicatorIcon() { 339 var choices = document.querySelectorAll(".choices"); 340 if (choices.length === 0) { 341 return; 342 } 343 344 for (var i = 0, len = choices.length; i < len; i++) { 345 var item = choices[i]; 346 var icon = document.createElement("div"); 347 var select = item.querySelector("select"); 348 icon.classList.add("icon-wrap"); 349 350 if (select.dataset.icon) { 351 switch (select.dataset.icon) { 352 case "exchange-alt": 353 icon.innerHTML = 354 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M0 168v-16c0-13.255 10.745-24 24-24h360V80c0-21.367 25.899-32.042 40.971-16.971l80 80c9.372 9.373 9.372 24.569 0 33.941l-80 80C409.956 271.982 384 261.456 384 240v-48H24c-13.255 0-24-10.745-24-24zm488 152H128v-48c0-21.314-25.862-32.08-40.971-16.971l-80 80c-9.372 9.373-9.372 24.569 0 33.941l80 80C102.057 463.997 128 453.437 128 432v-48h360c13.255 0 24-10.745 24-24v-16c0-13.255-10.745-24-24-24z"/></svg>'; 355 break; 356 case "calendar-alt": 357 icon.innerHTML = 358 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V192H0v272zm320-196c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM192 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM64 268c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0 112v48h448v-48c0-26.5-21.5-48-48-48z"/></svg>'; 359 break; 360 case "history": 361 icon.innerHTML = 362 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-2
3621.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z"/></svg>'; 363 break; 364 } 365 } else { 366 icon.innerHTML = 367 '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>'; 368 } 369 item.appendChild(icon); 370 } 371 })(); 372 } 373 374 return { init: init }; 375})(); 376 377var getParams = function (url) { 378 var params = {}; 379 var parser = document.createElement("a"); 380 parser.href = url; 381 var query = parser.search.substring(1); 382 var vars = query.split("&"); 383 for (var i = 0; i < vars.length; i++) { 384 var pair = vars[i].split("="); 385 params[pair[0]] = decodeURIComponent(pair[1]); 386 } 387 return params; 388}; 389 390(function euwidMarkets() { 391 var $params = getParams(window.location.href); 392 if (typeof $params !== "undefined") { 393 if (typeof $params["tab"] !== "undefined" && $params["tab"] !== "") { 394 var tab = $params["tab"]; 395 var marketNav = document.querySelector(".market-nav"); 396 var tabContent = document.querySelector(".wrap-tab-content"); 397 if (marketNav && tabContent) { 398 // loop through tabs 399 var marketNavItem = marketNav.querySelectorAll(".nav-item"), 400 visibleTabs = tabContent.querySelectorAll(".tab-content"); 401 for (var i = 0, len = marketNavItem.length; i < len; i++) { 402 // tabs 403 if (marketNavItem[i].dataset.tabHeaderId === tab) { 404 marketNavItem[i].classList.add("tab-header--active"); 405 } else { 406 marketNavItem[i].classList.remove("tab-header--active"); 407 } 408 // tab content 409 if (visibleTabs[i].dataset.tabContentId === tab) { 410 visibleTabs[i].style.display = "block"; 411 } else { 412 visibleTabs[i].style.display = "none"; 413 } 414 } 415 } 416 } 417 } 418})(); 419 420if (styledSelects) { 421 styledSelects.init(); 422} 423 424(function disableSelectOnMarketsPrice() { 425 var targets = document.querySelectorAll(".markets [data-tab-header-id]"); 426 if (targets.length === 0) { 427 return; 428 } 429 var select = document 430 .querySelector("#market__periodSelector") 431 .closest(".market__episode"); 432 for (var i = 0, len = targets.length; i < len; i++) { 433 var target = targets[i]; 434 (function (target) { 435 if (target !== null) { 436 target.addEventListener("click", function () { 437 if (select) { 438 if (target.dataset.tabHeaderId == 2) { 439 select.classList.add("hidden"); 440 select.parentNode 441 .querySelector(".label") 442 .classList.add("hidden"); 443 } else { 444 select.classList.remove("hidden"); 445 select.parentNode 446 .querySelector(".label") 447 .classList.remove("hidden"); 448 } 449 } 450 }); 451 } 452 })(target); 453 } 454})(); 455 456(function marketsOverviewScroll() { 457 filter = document.querySelector("#filter__search"); 458 if (!filter) { 459 return; 460 } 461 var timeout; 462 filter.addEventListener("keydown", function () { 463 clearTimeout(); 464 timeout = setTimeout(function () { 465 $("html, body").animate( 466 { 467 scrollTop: 468 $(".markets .section-grey").offset().top - 469 document.querySelector(".header").clientHeight, 470 }, 471 500 472 ); 473 }, 1000); 474 }); 475})(); 476 477(function listStylingFrameGrey() { 478 var frames = document.querySelectorAll(".frame-grey-round"); 479 if (!frames.length) return; 480
481 frames.forEach(function (frame) { 482 var ul = frame.querySelectorAll("ul"); 483 if (!ul.length) return; 484 485 ul.forEach(function (list) { 486 list.classList.add("list"); 487 list.classList.add("list--checkmarks"); 488 var items = list.querySelectorAll("li"); 489 items.forEach(function (item) { 490 item.classList.add("copy"); 491 item.classList.add("list-item"); 492 var icon = document.createElement("div"); 493 icon.innerHTML = 494 '<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"></path></svg>'; 495 $(item).prepend(icon); 496 }); 497 }); 498 }); 499})(); 500 501var specialSelects = (function () { 502 function setGroup() { 503 var valuemaps = document.querySelectorAll(".valuemap"); 504 valuemaps.length && 505 (function () { 506 for (var i = 0, len = valuemaps.length; i < len; i++) { 507 var valuemap = valuemaps[i]; 508 var choicesSelect = 509 valuemap.nextElementSibling.querySelector("select"); 510 var groupDOM = 511 valuemap.nextElementSibling.nextElementSibling.querySelector( 512 ".target" 513 ); 514 var groupValue = JSON.parse(valuemap.innerHTML)[ 515 choicesSelect.firstChild.value 516 ]; 517 if (groupValue) { 518 groupDOM.innerHTML = groupValue; 519 groupDOM.parentNode.classList.remove("invisible"); 520 } else { 521 groupDOM.parentNode.classList.add("invisible"); 522 } 523 } 524 })(); 525 } 526 527 function addEventListenerForTabOne() { 528 var target = document.querySelector( 529 '[data-tab-content-id="0"] .choices' 530 ); 531 if (target) target.addEventListener("click", setGroup); 532 } 533 534 return { 535 setGroup: setGroup, 536 addEventListenerForTabOne: addEventListenerForTabOne, 537 }; 538})(); 539 540/** 541 * Object.assign() polyfill for IE11 542 * @see <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign> 543 */ 544if (typeof Object.assign != "function") { 545 Object.defineProperty(Object, "assign", { 546 value: function assign(target, varArgs) { 547 "use strict"; 548 if (target == null) { 549 throw new TypeError( 550 "Cannot convert undefined or null to object" 551 ); 552 } 553 var to = Object(target); 554 for (var index = 1; index < arguments.length; index++) { 555 var nextSource = arguments[index]; 556 if (nextSource != null) { 557 for (var nextKey in nextSource) { 558 if ( 559 Object.prototype.hasOwnProperty.call( 560 nextSource, 561 nextKey 562 ) 563 ) { 564 to[nextKey] = nextSource[nextKey]; 565 } 566 } 567 } 568 } 569 return to; 570 }, 571 writable: true, 572 configurable: true, 573 }); 574} 575 576function openMarktbericht() { 577 $("html, body").animate({ scrollTop: 0 }); 578 setTimeout(function () { 579 document.querySelector(".tab-header.tab3").click(); 580 }, 500); 581} 582 583(function marketOverviewSelectState() { 584 var targets = document.querySelectorAll(".filter__buttons .category"); 585 if (!targets.length) return; 586 587 function deselectOthers(keep) { 588 targets.forEach(function (el) { 589 if (el === keep) return; 590 el.classList.remove("selected"); 591 el.selected = false;
592 }); 593 } 594 595 targets.forEach(function (el) { 596 el.selected = false; 597 el.addEventListener("click", function () { 598 deselectOthers(this); 599 if (this.selected) this.classList.remove("selected"); 600 else this.classList.add("selected"); 601 this.selected = !this.selected; 602 }); 603 }); 604})(); 605 606// ## smooth scroll anker links [ 607(function () { 608 var targets = document.querySelectorAll("a"); 609 if (!targets.length) return; 610 targets.forEach(function (el) { 611 if (el.href.indexOf("#") === -1) return; 612 var id = el.href.split("#")[1]; 613 if (id) { 614 el.addEventListener("click", function (e) { 615 e.preventDefault(); 616 $([document.documentElement, document.body]).animate( 617 { 618 scrollTop: $("#" + id).offset().top - 170, 619 }, 620 500 621 ); 622 }); 623 } 624 }); 625})(); 626// ## ] 627 628// ## form button styling [ 629(function () { 630 var targets = document.querySelectorAll( 631 ".frame-type-form_formframework .btn" 632 ); 633 if (!targets.length) return; 634 targets.forEach(function (el) { 635 el.className = "button--load-more button loadMore badge"; 636 }); 637})(); 638// ## ] 639 640// ## button alignment [ 641(function () { 642 var targets = document.querySelectorAll('.button[class*="align"]'); 643 if (!targets.length) return; 644 targets.forEach(function (el) { 645 var className = el.classList[el.classList.length - 1]; 646 el.classList.remove(className); 647 el.parentNode.classList.add(className); 648 }); 649})(); 650// ] 651 652// ## profit tiles [ 653(function () { 654 var wrap = document.querySelector(".profit-tiles"); 655 if (!wrap) return; 656 imagesLoaded(wrap, function () { 657 var tiles = wrap.querySelectorAll(".grid__element"); 658 if (!tiles.length) return; 659 660 tiles.forEach(function (el) { 661 el.top = el.children[0]; 662 el.bottom = el.children[1]; 663 }); 664 665 function setHeights() { 666 if (!tiles[0].clientHeight) return; 667 var highestTop = 0; 668 var highestBottom = 0; 669 670 tiles.forEach(function (el) { 671 if (el.top.clientHeight > highestTop) 672 highestTop = el.top.clientHeight; 673 if (el.bottom.clientHeight > highestBottom) 674 highestBottom = el.bottom.clientHeight; 675 }); 676 677 tiles.forEach(function (el) { 678 el.top.style.height = highestTop + "px"; 679 el.bottom.style.height = highestBottom + "px"; 680 }); 681 } 682 683 setHeights(); 684 window.addEventListener("resize", setHeights); 685 window.addEventListener("orientationchange", setHeights); 686 }); 687})(); 688// ## ] 689 690// ## scroll after load more [ 691// Entfernt: Dieser Block erzwang nach jedem "mehr laden"-Klick 1 Sekunde lang (bei ~60fps) 692// document.documentElement.scrollTop = pos und sperrte damit jeden Scrollversuch -> Seite stand 693// "auf der Stelle" und flackerte. Ãberflüssig, da die neuen Items unten an #newsitems angehängt 694// werden und die aktuelle Scroll-Position des Nutzers dadurch ohnehin nicht verschoben wird. 695// ] 696 697// ## bookmark-fn [ 698var bookmarkFunctions = (function () { 699 function resetBookmark() { 700 var allGradeSelectors = document.querySelectorAll( 701 ".modal__wrapper.show .bookmark__select" 702 ); 703 for (var i = 0, len = allGradeSelectors.length; i < len; i++) { 704 var currentSelect = allGradeSelectors[i]; 705 currentSelect[currentSelect.selectedIndex].removeAttribute( 706 "selected", 707 "selected" 708 ); 709 currentSelect.value = ""; 710 currentSelect[currentSelect.selectedIndex].setAttribute( 711 "selected", 712 "selected" 713 ); 714 $(allGradeSelectors[i]).selectric("refresh"); 715 } 716 var openBookmarkSettings = document.querySelector( 717 ".modal__wrapper.show" 718 ); 719 if (openBookmarkSettings) { 720 if (openBookmarkSettings.querySelector(".bookmark__btn")) 721 openBookmarkSettings 722 .querySelector(".bookmark__btn") 723 .setAttribute("disabled", ""); 724 openBookmarkSettings.classList.remove("show"); 725 } 726 727 // remove login 728 var loginForm = document.getElementById("loginform"); 729 if (loginForm) { 730 loginForm.parentNode.removeChild(loginForm); 731 } 732 return false;
733 } 734 735 function bookmarkSettings(el) { 736 var sendData = function (dataObj, reset) { 737 var xhr = new XMLHttpRequest(); 738 xhr.open( 739 "POST", 740 "/?type=1640113930700&tx_euwiddashboard_euwiddashboard[action]=saveBookmark", 741 true 742 ); 743 xhr.setRequestHeader( 744 "Content-Type", 745 "application/x-www-form-urlencoded" 746 ); 747 xhr.onreadystatechange = function () { 748 if ( 749 this.readyState === XMLHttpRequest.DONE && 750 this.status === 200 751 ) { 752 } 753 }; 754 xhr.send("data=" + dataObj); 755 if (reset) { 756 resetBookmark(); 757 } 758 }; 759 760 var brk = closestByClass(el, "bookmark"), 761 brkType = brk.dataset.type, 762 bookmarkBtn = closestByClass(el, "modal__cntr").querySelector( 763 ".bookmark__btn" 764 ), 765 dataObj = { 766 type: brkType, 767 config: {}, 768 }; 769 switch (brkType) { 770 case "markets": 771 var allGradeSelectors = closestByClass( 772 el, 773 "modal__cntr" 774 ).querySelectorAll(".bookmark__select"), 775 grades = "", 776 gradeNames = ""; 777 if (allGradeSelectors) { 778 for ( 779 var i = 0, len = allGradeSelectors.length; 780 i < len; 781 i++ 782 ) { 783 if (allGradeSelectors[i].value !== "") { 784 if (grades === "") { 785 grades = allGradeSelectors[i].value; 786 } else { 787 grades += "," + allGradeSelectors[i].value; 788 } 789 if (gradeNames === "") { 790 gradeNames = 791 allGradeSelectors[i].options[ 792 allGradeSelectors[i].selectedIndex 793 ].innerText.trim(); 794 } else { 795 gradeNames += 796 "," + 797 allGradeSelectors[i].options[ 798 allGradeSelectors[i].selectedIndex 799 ].innerText.trim(); 800 } 801 } 802 } 803 } 804 // add data to object 805 dataObj.config.market = brk.dataset.marketUid; 806 if ( 807 document.getElementById("market__periodSelector") !== null 808 ) { 809 dataObj.config.period = document.getElementById( 810 "market__periodSelector" 811 ).value; 812 } else { 813 if (typeof brk.dataset.periodUid !== "undefined") { 814 dataObj.config.period = brk.dataset.periodUid; 815 } 816 } 817 // grades 818 dataObj.config.grades = grades; 819 820 // if button disabled send data 821 if (brk.dataset.settings === "1") { 822 if (bookmarkBtn.disabled === false) { 823 // object to json 824 dataObj = JSON.stringify(dataObj); 825 826 // tracking 827 _mtm.push({ 828 event: "addMarket", 829 comparedMarkets: gradeNames, 830 }); 831 832 // send data & and flash 833 sendData(dataObj, 1); 834 flashMessage("markets", "grades", "add", 0); 835 } 836 } 837 838 // if no grades 839 if (brk.dataset.marketReportonly === "1") { 840 // object to json 841 dataObj = JSON.stringify(dataObj); 842 sendData(dataObj, 0); 843 flashMessage("markets", "single", "addreport", 0); 844 } 845 break; 846 case "news": 847 if (brk.dataset.keywordsUid !== "") { 848 dataObj.config.keywords = brk.dataset.keywordsUid; 849 } 850 if (brk.dataset.companyKeywordsUid !== "") { 851 dataObj.config.companykeywords = 852 brk.dataset.companyKeywordsUid; 853 } 854 if (brk.dataset.categoryUid !== "") { 855 dataObj.config.category = brk.dataset.categoryUid; 856 } 857 if (brk.dataset.newsUid !== "") { 858 dataObj.group = "bookmark"; 859 dataObj.config.news = brk.dataset.newsUid; 860 } 861 dataObj = JSON.stringify(dataObj); 862 sendData(dataObj, 0); 863 var addonFlashmessage = 864 brk.dataset.flashmessageLabel !== "" 865 ? brk.dataset.flashmessageLabel 866 : ""; 867 if (brk.dataset.newsUid !== "") { 868 flashMessage("news", "single", "add", 0); 869 } else if (brk.dataset.newsUid === "") { 870 var categoryUid = brk.dataset.categoryUid; 871 if ( 872 categoryUid !== "" && 873 typeof categoryUid !== "undefined" 874 ) { 875 flashMessage( 876 "news", 877 "category", 878 "add", 879 0, 880 addonFlashmessage 881 ); 882 } 883 var keywordsUid = brk.dataset.keywordsUid; 884 if ( 885 keywordsUid !== "" && 886 typeof keywordsUid !== "undefined" 887 ) { 888 flashMessage( 889 "news", 890 "keywords", 891 "add", 892 0, 893 addonFlashmessage 894 ); 895 } 896 var companyKeywordsUid = brk.dataset.companyKeywordsUid; 897 if ( 898 companyKeywordsUid !== "" && 899 typeof companyKeywordsUid !== "undefined" 900 ) { 901 flashMessage( 902 "news", 903 "companykeywords", 904 "add", 905 0, 906 addonFlashmessage 907 ); 908 } 909 } 910 911 // tracking 912 if (typeof el.dataset.clickEvent !== "undefined") { 913 _mtm.push( 914 JSON.parse(el.dataset.clickEvent.replace(/'/g, '"')) 915 ); 916 } 917 break;
918 case "recyclingexchange": 919 if (brk.dataset.recyclingexchangeUid !== "") { 920 dataObj.group = "bookmark"; 921 dataObj.config.recyclingexchange = 922 brk.dataset.recyclingexchangeUid; 923 } 924 dataObj = JSON.stringify(dataObj); 925 sendData(dataObj, 0); 926 flashMessage("recyclingexchange", "contact", "add", 0); 927 break; 928 case "search": 929 dataObj.config.filter = {}; 930 dataObj.config.sorting = {}; 931 dataObj.config.searchterm = document.querySelector( 932 'form#resultform input[type="text"]' 933 ).value; 934 935 var urlSearchParams = decodeURIComponent( 936 location.search.substring(1) 937 ).split("&"); 938 // clean url 939 for (var i = 0, len = urlSearchParams.length; i < len; i++) { 940 var paramValue = urlSearchParams[i].substring( 941 urlSearchParams[i].indexOf("=") + 1 942 ); 943 if (urlSearchParams[i].indexOf("tx_solr[filter]") > -1) { 944 dataObj.config.filter[i] = paramValue; 945 } else if ( 946 urlSearchParams[i].indexOf("tx_solr[group][sorting]") > 947 -1 948 ) { 949 dataObj.config.sorting = Object.assign( 950 {}, 951 paramValue.split("+") 952 ); 953 } 954 } 955 //dataObj.config.url = encodeURIComponent(location.search); 956 dataObj = JSON.stringify(dataObj); 957 sendData(dataObj, 0); 958 flashMessage("search", "searchterm", "add", 0); 959 break; 960 default: 961 return 0; 962 } 963 } 964 965 function hasJsonStructure(str) { 966 if (typeof str !== "string") return false; 967 try { 968 var result = JSON.parse(str); 969 var type = Object.prototype.toString.call(result); 970 return type === "[object Object]" || type === "[object Array]"; 971 } catch (err) { 972 return false; 973 } 974 } 975 976 function getFrontendLogin(target, dataObj, typeNum, btm) { 977 if (!target) var target = null; 978 if (!typeNum) var typeNum = 0; 979 if (!dataObj) var dataObj = null; 980 if (!btn) var btn = null; 981 return new Promise(function (resolve, reject) { 982 var xhr = new XMLHttpRequest(), 983 url = "/?type=1048&tx_euwiddashboard_login[action]=login"; 984 if (target) { 985 xhr.onload = function () { 986 if ( 987 this.readyState === XMLHttpRequest.DONE && 988 this.status === 200 989 ) { 990 target.innerHTML = ""; 991 target.innerHTML = this.responseText; 992 target.querySelector("#loginForm"); 993 frontendLogin(target, dataObj, typeNum, btn); 994 } 995 }; 996 xhr.onerror = reject; 997 xhr.open("GET", url); 998 xhr.setRequestHeader( 999 "Content-type", 1000 "application/x-www-form-urlencoded" 1001 ); 1002 xhr.send(); 1003 } 1004 }); 1005 } 1006 1007 function frontendLogin(target, dataObj, typeNum, btn) { 1008 if (!target) var target = null; 1009 if (!typeNum) var typeNum = 0; 1010 if (!dataObj) var dataObj = null; 1011 if (!btn) var btn = null; 1012 var loginForm = document.getElementById("loginform"); 1013 var xhr = new XMLHttpRequest(); 1014 if (loginForm) { 1015 var user = loginForm.querySelector("#user"), 1016 pass = loginForm.querySelector("#pass"); 1017 if (user && pass) { 1018 xhr.onreadystatechange = function () { 1019 if (this.readyState === 4 && this.status === 200) { 1020 loginForm.classList.remove("loading"); 1021 if ( 1022 this.responseText.trim().length > 0 && 1023 hasJsonStructure(this.responseText.trim()) 1024 ) {
1025 var validation = JSON.parse( 1026 this.responseText.trim() 1027 ); 1028 if ( 1029 validation.user === true && 1030 validation.pass === true 1031 ) { 1032 if (user.parentNode.classList.contains("error")) 1033 user.parentNode.classList.remove("error"); 1034 if (pass.parentNode.classList.contains("error")) 1035 pass.parentNode.classList.remove("error"); 1036 1037 // remove login form 1038 loginForm.parentNode.removeChild(loginForm); 1039 1040 // callback 1041 if (target !== null && dataObj) { 1042 getSettings(dataObj, typeNum, btn); 1043 } else { 1044 var openBookmark = document.querySelector( 1045 ".modal__wrapper.show" 1046 ).parentNode; 1047 bookmarkSettings(openBookmark); 1048 resetBookmark(); 1049 } 1050 } else { 1051 validation.user === false 1052 ? user.parentNode.classList.add("error") 1053 : user.parentNode.classList.remove("error"); 1054 validation.pass === false 1055 ? pass.parentNode.classList.add("error") 1056 : pass.parentNode.classList.remove("error"); 1057 } 1058 } 1059 } 1060 }; 1061 if (loginForm) { 1062 loginForm 1063 .querySelector("#submit") 1064 .addEventListener("click", function (e) { 1065 e.preventDefault(); 1066 loginForm.classList.add("loading"); 1067 var url = loginForm.dataset.action, 1068 formData = {}; 1069 formData = new FormData(loginForm); 1070 formData = new URLSearchParams(formData).toString(); 1071 1072 xhr.open("POST", url, true); 1073 xhr.setRequestHeader( 1074 "Content-type", 1075 "application/x-www-form-urlencoded" 1076 ); 1077 xhr.send(formData); 1078 }); 1079 } 1080 } 1081 } 1082 } 1083 1084 function checkUserLoggedIn() { 1085 return new Promise(function (resolve, reject) { 1086 var xhr = new XMLHttpRequest(); 1087 xhr.onload = function () { 1088 if ( 1089 this.readyState === XMLHttpRequest.DONE && 1090 this.status === 200 1091 ) { 1092 if ( 1093 this.responseText.trim().length > 0 && 1094 hasJsonStructure(this.responseText.trim()) 1095 ) { 1096 var loginStatusTemp = JSON.parse( 1097 this.responseText.trim() 1098 ); 1099 resolve(loginStatusTemp.loginstatus); 1100 } 1101 } 1102 }; 1103 xhr.onerror = reject; 1104 xhr.open("GET", "/?type=1049&tx_euwiddashboard_login[action]=checkUser", true); 1105 xhr.send(); 1106 }); 1107 } 1108 1109 function getSettings(dataObj, type, btn) { 1110 if (!dataObj) var dataObj = {}; 1111 if (!type) var type = 0; 1112 if (!btn) var btn = null; 1113 if (Object.keys(dataObj).length > 1 && type > 0) { 1114 var xhr = new XMLHttpRequest(); 1115 xhr.open("POST", "/?type=" + type + "&tx_euwidmarkets_index[action]=bookmarkcontent", true); 1116 xhr.setRequestHeader( 1117 "Content-Type", 1118 "application/x-www-form-urlencoded" 1119 ); 1120 xhr.onreadystatechange = function () { 1121 if ( 1122 this.readyState === XMLHttpRequest.DONE && 1123 this.status === 200 1124 ) { 1125 // replace content with loaded settings 1126 var sc = document.querySelector( 1127 ".modal__wrapper.show .bookmark__settings__fields" 1128 ); 1129 if (sc) { 1130 sc.innerHTML = this.response; 1131 sc.classList.remove("loading"); 1132 } 1133 1134 // init selectric 1135 marketsFn.initSelectric(); 1136 1137 // add selectors 1138 if (btn) { 1139 btn.removeEventListener("click", function () {}); 1140 btn.addEventListener("click", function () { 1141 bookmarkSettings(this); 1142 }); 1143 } 1144 } 1145 if ( 1146 this.readyState === XMLHttpRequest.DONE && 1147 this.status === 500 1148 ) { 1149 document.querySelector( 1150 ".modal__wrapper.show .bookmark__settings__fields" 1151 ).innerHTML = this.response; 1152 } 1153 }; 1154 xhr.send("data=" + dataObj); 1155 } 1156 } 1157 1158 // root (optional): nur innerhalb dieses Elements binden. Ohne Argument die ganze Seite. 1159 // Wird beim News-"mehr laden" mit dem neuen Chunk aufgerufen, damit nicht bei jeder 1160 // Nachladung ALLE bereits geladenen Teaser erneut gebunden werden (O(n) pro Load -> Ruckler). 1161 function bookmarkFunction(root) { 1162 var brk = (root || document).querySelectorAll(".bookmark"); 1163 var timeout; 1164 1165 Array.prototype.forEach.call(brk, function (singleBookmark) { 1166 var thisEl = singleBookmark.querySelector(".save__to_bookmarks"); 1167 thisEl.onclick = function (event) { 1168 event.preventDefault(); 1169 event.stopPropagation(); 1170 if ( 1171 thisEl.nextElementSibling && 1172 !thisEl.nextElementSibling.classList.contains("show") 1173 ) { 1174 var parentEl = thisEl.parentNode, 1175 bookmarkBtn = parentEl.querySelector(".bookmark__btn"); 1176 1177 if (parentEl.dataset.showlogin === "1") { 1178 document 1179 .querySelector(".bookmark-paywall.modal__wrapper") 1180 .classList.add("show"); 1181 if ( 1182 document.querySelector( 1183 ".bookmark-paywall.modal__wrapper .modal__close" 1184 ) 1185 ) { 1186 document 1187 .querySelector( 1188 ".bookmark-paywall.modal__wrapper .modal__close" 1189 ) 1190 .removeEventListener("click", function () {}); 1191 document 1192 .querySelector( 1193 ".bookmark-paywall.modal__wrapper .modal__close" 1194 ) 1195 .addEventListener("click", function (event) { 1196 event.preventDefault(); 1197 event.stopPropagation(); 1198 document 1199 .querySelector( 1200 ".bookmark-paywall.modal__wrapper" 1201 ) 1202 .classList.remove("show"); 1203 return false;
1204 }); 1205 } 1206 // if settings is enabled 1207 // element has config (like Markets) or not (like news). 1208 } else { 1209 if (parentEl.dataset.settings === "1") { 1210 thisEl.nextElementSibling.classList.add("show"); 1211 1212 // dataObj 1213 var dataObj = {}; 1214 var settingsEl = document.querySelector( 1215 ".modal__wrapper.show .bookmark__settings__fields" 1216 ); 1217 if (settingsEl) { 1218 dataObj.marketUid = 1219 settingsEl.dataset.marketUid; 1220 dataObj.serviceUid = 1221 settingsEl.dataset.serviceUid; 1222 1223 // object to json 1224 dataObj = JSON.stringify(dataObj); 1225 1226 checkUserLoggedIn().then(function (result) { 1227 if (result) { 1228 getSettings(dataObj, 1034, bookmarkBtn); 1229 } else { 1230 getFrontendLogin( 1231 settingsEl, 1232 dataObj, 1233 1034, 1234 bookmarkBtn 1235 ); 1236 } 1237 }); 1238 } 1239 } else if (parentEl.dataset.marketReportonly === "1") { 1240 if ( 1241 typeof parentEl.dataset.duration !== "undefined" 1242 ) { 1243 bookmarkSettings(thisEl); 1244 } else { 1245 if (bookmarkBtn) { 1246 bookmarkBtn.removeAttribute("disabled"); 1247 // add selectors 1248 bookmarkBtn.removeEventListener( 1249 "click", 1250 function () {} 1251 ); 1252 bookmarkBtn.addEventListener( 1253 "click", 1254 function () { 1255 bookmarkSettings(thisEl); 1256 } 1257 ); 1258 } 1259 } 1260 } else { 1261 bookmarkSettings(thisEl); 1262 } 1263 1264 // if duration close automatically 1265 if (typeof parentEl.dataset.duration !== "undefined") { 1266 clearTimeout(timeout); 1267 timeout = setTimeout( 1268 resetBookmark, 1269 parentEl.dataset.duration 1270 ); 1271 } 1272 1273 // close 1274 if (parentEl.querySelector(".modal__close")) { 1275 parentEl 1276 .querySelector(".modal__close") 1277 .removeEventListener("click", function () {}); 1278 parentEl 1279 .querySelector(".modal__close") 1280 .addEventListener("click", function (event) { 1281 event.preventDefault(); 1282 event.stopPropagation(); 1283 resetBookmark(); 1284 return false; 1285 }); 1286 } 1287 } 1288 } 1289 return false;
1290 }; 1291 }); 1292 // click open settings 1293 if (brk.length > 0) { 1294 document.addEventListener( 1295 "click", 1296 function (event) { 1297 if (document.querySelector(".modal__wrapper.show")) { 1298 if (event.target.matches(".modal__wrapper")) { 1299 clearTimeout(timeout); 1300 resetBookmark(); 1301 } 1302 } 1303 }, 1304 false 1305 ); 1306 1307 document.addEventListener("keydown", function (e) { 1308 if (e.key === "Escape" || e.key === 27) { 1309 clearTimeout(timeout); 1310 resetBookmark(); 1311 } 1312 }); 1313 } 1314 1315 return { getSettings: getSettings }; 1316 } 1317 1318 // dom content loaded 1319 document.addEventListener("DOMContentLoaded", function () { 1320 bookmarkFunction(); 1321 }); 1322 1323 return { 1324 bookmark: bookmarkFunction, 1325 }; 1326})(); 1327// ] 1328 1329// ## landingpage handling [ 1330if (document.querySelector(".is-landingpage")) 1331 document.body.classList.add("landingpage"); 1332// ## ] 1333 1334// ## lp stoerer [ 1335(function () { 1336 var target = document.querySelector(".stoerer"); 1337 if (!target) return; 1338 var img = target.querySelector("img"); 1339 target.previousSibling.appendChild(img); 1340 target.previousSibling.style.position = "relative"; 1341 img.classList.add("stoerer-img"); 1342 if (Array.prototype.slice.call(target.classList).indexOf("top") !== -1) 1343 img.classList.add("top"); 1344})(); 1345// ## ] 1346/* disabled because of rebuilöd the submit svg to button, js not longer needed 1347(function() { 1348 var searchBox = document.querySelector('#search-box'); 1349 if (searchBox !== null) { 1350 var button = searchBox.querySelector('.header-search__button'); 1351 button.addEventListener('click', function() { 1352 searchBox.submit(); 1353 }); 1354 } 1355})(); 1356*/ 1357 1358/* 1359// ## search suggester [ 1360(function() { 1361 Array.prototype.forEach.call(document.querySelectorAll('.search-suggest'), function(suggest) { 1362 suggest.addEventListener('keyup', function() { 1363 if (suggest.value.length > 2) { 1364 var form = new FormData(); 1365 form.append('tx_euwidsearch_euwidsearch[query]', suggest.value); 1366 fetch('/?type=1603733023531', { 1367 method: 'POST', 1368 body: form 1369 }).then(function (response) { 1370 return response.json(); 1371 }).then(function(data) { 1372 var list = data.spellcheck.suggestions[1].suggestion; 1373 var dataList = suggest.parentNode.querySelector('datalist'); 1374 dataList.innerHTML = ""; 1375 Array.prototype.forEach.call(list, function(elem) { 1376 var option = document.createElement('option'); 1377 option.innerHTML = elem; 1378 dataList.append(option); 1379 }); 1380 }); 1381 } 1382 }); 1383 }); 1384})(); 1385// ## ] 1386*/ 1387 1388// ## flashmessages with toastr [ 1389function flashMessage(area, item, action, title, addonFlashmessage) { 1390 if (!title) var title = 1; 1391 if (!addonFlashmessage) var addonFlashmessage = ""; 1392 if (typeof flashmessagesLabels !== "undefined" && flashMessage) { 1393 var labels = flashmessagesLabels[area][item][action]; 1394 1395 // replace content in label 1396 if ( 1397 addonFlashmessage !== "" && 1398 labels.message.includes("###REPLACE###") 1399 ) { 1400 labels.message = labels.message.replace( 1401 "###REPLACE###", 1402 addonFlashmessage 1403 ); 1404 } 1405 1406 // check if title is required 1407 if (title === 0) { 1408 toastr.success(labels.message); 1409 } else { 1410 toastr.success(labels.message, labels.title); 1411 } 1412 } 1413} 1414 1415// ## ] 1416/* 1417// ## search saver form [ 1418(function () { 1419 Array.prototype.forEach.call(document.querySelectorAll('form[name="search"]'), function (form) { 1420 form.addEventListener('submit', function (event) { 1421 event.stopPropagation(); 1422 event.preventDefault(); 1423 var formSubmit = new FormData(form); 1424 saveSearchForm(formSubmit, formReload, form); 1425 return false; 1426 }); 1427 }); 1428})(); 1429// ## ] 1430 1431var formReload = function (form) { 1432 window.location.href = form.getAttribute('action'); 1433} 1434 1435var saveSearchForm = function(formSubmit, callback, form) { 1436 if (!formSubmit || !formSubmit.append) return; 1437 formSubmit.append('tx_euwidsearch_euwidsearch[saveType]', '1'); 1438 fetch('/?type=1603964150683', { 1439 method: 'POST', 1440 body: formSubmit 1441 }).then(function (response) { 1442 return response.text(); 1443 }).then(function (text) { 1444 if (callback) { 1445 callback(form); 1446 } 1447 }); 1448}; 1449*/ 1450// ## logout menu handling [ 1451(function () { 1452 var target = document.querySelector("#euwid_logout"); 1453 if (!target) return; 1454 1455 var dropdown = document.querySelector(".account-dropdown"); 1456 1457 dropdown.querySelector(".logout").addEventListener("click", function () { 1458 target.submit(); 1459 }); 1460 1461 var link = target.querySelector("a"); 1462 link.addEventListener("click", function (e) { 1463 dropdown.classList.toggle("active"); 1464 }); 1465})(); 1466// ## ] 1467 1468// ## start-page handling [ 1469if (document.querySelector(".header-modul")) 1470 document.body.classList.add("start-page"); 1471 1472// ## ] 1473 1474function _toConsumableArray(arr) { 1475 return ( 1476 _arrayWithoutHoles(arr) || 1477 _iterableToArray(arr) || 1478 _unsupportedIterableToArray(arr) || 1479 _nonIterableSpread() 1480 ); 1481} 1482 1483function _nonIterableSpread() { 1484 throw new TypeError( 1485 "Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method." 1486 ); 1487} 1488 1489function _unsupportedIterableToArray(o, minLen) { 1490 if (!o) return; 1491 if (typeof o === "string") return _arrayLikeToArray(o, minLen); 1492 var n = Object.prototype.toString.call(o).slice(8, -1); 1493 if (n === "Object" && o.constructor) n = o.constructor.name; 1494 if (n === "Map" || n === "Set") return Array.from(o); 1495 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) 1496 return _arrayLikeToArray(o, minLen); 1497} 1498 1499function _iterableToArray(iter) { 1500 if ( 1501 (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) || 1502 iter["@@iterator"] != null 1503 ) 1504 return Array.from(iter); 1505} 1506 1507function _arrayWithoutHoles(arr) { 1508 if (Array.isArray(arr)) return _arrayLikeToArray(arr); 1509} 1510 1511function _arrayLikeToArray(arr, len) { 1512 if (len == null || len > arr.length) len = arr.length; 1513 for (var i = 0, arr2 = new Array(len); i < len; i++) { 1514 arr2[i] = arr[i]; 1515 } 1516 return arr2; 1517} 1518 1519function _classCallCheck(instance, Constructor) { 1520 if (!(instance instanceof Constructor)) { 1521 throw new TypeError("Cannot call a class as a function"); 1522 } 1523} 1524 1525function _defineProperties(target, props) { 1526 for (var i = 0; i < props.length; i++) { 1527 var descriptor = props[i]; 1528 descriptor.enumerable = descriptor.enumerable || false; 1529 descriptor.configurable = true; 1530 if ("value" in descriptor) descriptor.writable = true; 1531 Object.defineProperty(target, descriptor.key, descriptor); 1532 } 1533} 1534 1535function _createClass(Constructor, protoProps, staticProps) { 1536 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 1537 if (staticProps) _defineProperties(Constructor, staticProps); 1538 return Constructor; 1539} 1540 1541// ## news carousel [ 1542(function () { 1543 if (isIE11) return; 1544 var galCon = document.querySelector(".gallery-container"); 1545 if (!galCon) return; 1546 var galleryContainer = document.querySelector(".gallery-container");
1547 var galleryControlsContainer = document.querySelector(".gallery-controls"); 1548 var galleryControls = ["previous", "next"]; 1549 var galleryItems = document.querySelectorAll(".gallery-item"); 1550 1551 var Carousel = /*#__PURE__*/ (function () { 1552 function Carousel(container, items, controls) { 1553 _classCallCheck(this, Carousel); 1554 1555 this.carouselContainer = container; 1556 this.carouselControls = controls; 1557 this.carouselArray = _toConsumableArray(items); 1558 } 1559 1560 _createClass(Carousel, [ 1561 { 1562 key: "setInitialState", 1563 value: function setInitialState() { 1564 1565 if (this.carouselArray[0]) { 1566 this.carouselArray[0].classList.add("gallery-item-first"); 1567 } 1568 if (this.carouselArray[1]) { 1569 this.carouselArray[1].classList.add("gallery-item-previous"); 1570 } 1571 if (this.carouselArray[2]) { 1572 this.carouselArray[2].classList.add("gallery-item-selected"); 1573 } 1574 if (this.carouselArray[3]) { 1575 this.carouselArray[3].classList.add("gallery-item-next"); 1576 } 1577 if (this.carouselArray[4]) { 1578 this.carouselArray[4].classList.add("gallery-item-last"); 1579 } 1580 1581 var navNodes = document.querySelector(".gallery-nav").childNodes; 1582 if (navNodes[0]) { 1583 navNodes[0].className = "gallery-nav-item gallery-item-first"; 1584 } 1585 if (navNodes[1]) { 1586 navNodes[1].className = "gallery-nav-item gallery-item-previous"; 1587 } 1588 if (navNodes[2]) { 1589 navNodes[2].className = "gallery-nav-item gallery-item-selected"; 1590 } 1591 if (navNodes[3]) { 1592 navNodes[3].className = "gallery-nav-item gallery-item-next"; 1593 } 1594 if (navNodes[4]) { 1595 navNodes[4].className = "gallery-nav-item gallery-item-last"; 1596 } 1597 }, 1598 }, 1599 { 1600 key: "setCurrentState", 1601 value: function setCurrentState( 1602 target, 1603 selected, 1604 previous, 1605 next, 1606 first, 1607 last 1608 ) { 1609 selected.forEach(function (el) { 1610 el.classList.remove("gallery-item-selected"); 1611 1612 if (target.className == "gallery-controls-previous") { 1613 el.classList.add("gallery-item-next"); 1614 } else { 1615 el.classList.add("gallery-item-previous"); 1616 } 1617 }); 1618 previous.forEach(function (el) { 1619 el.classList.remove("gallery-item-previous"); 1620 1621 if (target.className == "gallery-controls-previous") { 1622 el.classList.add("gallery-item-selected"); 1623 } else { 1624 el.classList.add("gallery-item-first"); 1625 } 1626 }); 1627 next.forEach(function (el) { 1628 el.classList.remove("gallery-item-next"); 1629 1630 if (target.className == "gallery-controls-previous") { 1631 el.classList.add("gallery-item-last"); 1632 } else { 1633 el.classList.add("gallery-item-selected"); 1634 } 1635 }); 1636 first.forEach(function (el) { 1637 el.classList.remove("gallery-item-first"); 1638 1639 if (target.className == "gallery-controls-previous") { 1640 el.classList.add("gallery-item-previous"); 1641 } else { 1642 el.classList.add("gallery-item-last"); 1643 } 1644 }); 1645 last.forEach(function (el) { 1646 el.classList.remove("gallery-item-last"); 1647 1648 if (target.className == "gallery-controls-previous") { 1649 el.classList.add("gallery-item-first"); 1650 } else { 1651 el.classList.add("gallery-item-next"); 1652 } 1653 }); 1654 }, 1655 }, 1656 { 1657 key: "setNav", 1658 value: function setNav() { 1659 galleryContainer.appendChild( 1660 document.createElement("ul") 1661 ).className = "gallery-nav"; 1662 this.carouselArray.forEach(function (item) { 1663 var nav = galleryContainer.lastElementChild; 1664 nav.appendChild(document.createElement("li")); 1665 }); 1666 }, 1667 }, 1668 { 1669 key: "setControls", 1670 value: function setControls() {
1671 this.carouselControls.forEach(function (control) { 1672 galleryControlsContainer.appendChild( 1673 document.createElement("button") 1674 ).className = "gallery-controls-".concat(control); 1675 }); 1676 !!galleryControlsContainer.childNodes[0] 1677 ? (galleryControlsContainer.childNodes[0].innerHTML = 1678 null) 1679 : null; 1680 !!galleryControlsContainer.childNodes[1] 1681 ? (galleryControlsContainer.childNodes[1].innerHTML = 1682 null) 1683 : null; 1684 }, 1685 }, 1686 { 1687 key: "useControls", 1688 value: function useControls() { 1689 var _this = this; 1690 1691 var triggers = _toConsumableArray( 1692 galleryControlsContainer.childNodes 1693 ); 1694 1695 triggers.forEach(function (control) { 1696 control.addEventListener("click", function () { 1697 var target = control; 1698 var selectedItem = document.querySelectorAll( 1699 ".gallery-item-selected" 1700 ); 1701 var previousSelectedItem = 1702 document.querySelectorAll( 1703 ".gallery-item-previous" 1704 ); 1705 var nextSelectedItem = 1706 document.querySelectorAll(".gallery-item-next"); 1707 var firstCarouselItem = document.querySelectorAll( 1708 ".gallery-item-first" 1709 ); 1710 var lastCarouselItem = 1711 document.querySelectorAll(".gallery-item-last"); 1712 1713 _this.setCurrentState( 1714 target, 1715 selectedItem, 1716 previousSelectedItem, 1717 nextSelectedItem, 1718 firstCarouselItem, 1719 lastCarouselItem 1720 ); 1721 }); 1722 }); 1723 }, 1724 }, 1725 ]); 1726 1727 return Carousel; 1728 })(); 1729 1730 var exampleCarousel = new Carousel( 1731 galleryContainer, 1732 galleryItems, 1733 galleryControls 1734 ); 1735 exampleCarousel.setControls(); 1736 exampleCarousel.setNav(); 1737 exampleCarousel.setInitialState(); 1738 exampleCarousel.useControls(); 1739 var prev = document.querySelector(".gallery-controls-previous"); 1740 var next = document.querySelector(".gallery-controls-next"); 1741 galCon.addEventListener("swiperight", function (e) { 1742 if (!prev) return; 1743 e.preventDefault(); 1744 e.stopPropagation(); 1745 prev.click(); 1746 }); 1747 galCon.addEventListener("swipeleft", function (e) { 1748 if (!prev) return; 1749 e.preventDefault(); 1750 e.stopPropagation(); 1751 next.click(); 1752 }); 1753})(); 1754 1755(function () { 1756 var target = document.querySelector(".gallery-controls-previous"); 1757 if (target) target.click(); 1758})(); // ## ] 1759 1760// ## search fix container wrapping [ 1761(function () { 1762 var target = document.querySelector(".remove-outer-container"); 1763 if (!target) return; 1764 target.parentNode.className = ""; 1765})(); 1766// ## ] 1767 1768// ## temp: service select class name [ 1769//(function () { 1770// var target = document.getElementById('serviceSelect') 1771// if (!target.return) 1772// target.parentNode.classList.add('service-select-wrap') 1773//})(); 1774// ## ] 1775 1776// ## scroll-to-top [ 1777(function () { 1778 var target = document.querySelector(".scroll-to-top"); 1779 if (!target) return; 1780 1781 function handle() { 1782 if ( 1783 window.scrollY > window.innerHeight * 1.5 || 1784 (window.innerHeight === document.body.clientHeight && 1785 window.scrollY === window.innerHeight) 1786 ) 1787 target.classList.add("show"); 1788 else target.classList.remove("show"); 1789 } 1790 1791 window.addEventListener("scroll", handle); 1792 window.addEventListener("load", handle); 1793 1794 target.addEventListener("click", function () { 1795 $("html, body").animate({ scrollTop: 0 }, 250); 1796 }); 1797})(); 1798// ## ] 1799 1800// quote element [ 1801(function () { 1802 var targets = document.querySelectorAll('.quote[id^="r"]'); 1803 if (!targets.length) return;
1804 targets.forEach(function (el) { 1805 if (el.querySelector("img")) { 1806 var image = el.querySelector("img").cloneNode(true); 1807 } 1808 var content = el.querySelector(".ce-bodytext").cloneNode(true); 1809 1810 el.innerHTML = '<div class="left"></div><div class="right"></div>'; 1811 var left = el.querySelector(".left"); 1812 var right = el.querySelector(".right"); 1813 if (image) left.appendChild(image); 1814 right.innerHTML = content.innerHTML; 1815 el.outerHTML = '<div class="quote-wrap">' + el.outerHTML + "</div>"; 1816 if (!image) 1817 el.querySelector(".left").parentNode.removeChild( 1818 el.querySelector(".left") 1819 ); 1820 }); 1821})(); 1822// ] 1823 1824// footer spacing mobile fix [ 1825(function () { 1826 var targets = document.querySelectorAll(".grid__element--bp-2-col"); 1827 if (!targets.length) return; 1828 targets.forEach(function (el) { 1829 if (!el.firstChild) el.style.marginBottom = "0px"; 1830 }); 1831})(); 1832// ] 1833 1834// ## global mobile device class [ 1835(function () { 1836 //if (/Android|webOS|iPhone|iPad|Mac|Macintosh|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { 1837 if (is_touch_enabled()) { 1838 document.body.classList.add("mobile-device"); 1839 (function () { 1840 var target = document.querySelector(".market-nav .nav-items"); 1841 if (!target) return; 1842 target.addEventListener("scroll", function () { 1843 if ( 1844 target.scrollLeft === 1845 target.scrollWidth - target.offsetWidth 1846 ) 1847 target.parentNode.parentNode.classList.add("end"); 1848 else target.parentNode.parentNode.classList.remove("end"); 1849 }); 1850 })(); 1851 } 1852})(); 1853// ## ] 1854 1855// ## function wrap string to html element [ 1856var htmlToElement = function (html, notFirstChild) { 1857 if (isIE11) { 1858 var el = document.createElement("div"); 1859 el.innerHTML = html; 1860 return notFirstChild ? el : el.firstElementChild; 1861 } 1862 var template = document.createElement("template"); 1863 html = html.trim(); // Never return a text node of whitespace as the result 1864 template.innerHTML = html; 1865 return notFirstChild ? template.content : template.content.firstChild; 1866}; 1867// ## ] 1868 1869var loadBoxLinks = function () { 1870 var boxes = document.getElementsByClassName("clickable"); 1871 Array.prototype.forEach.call(boxes, function (box) { 1872 box.onclick = function (event) { 1873 if (event.target.tagName !== "A") { 1874 event.stopPropagation(); 1875 event.preventDefault(); 1876 var link = box.querySelector("a"); 1877 link.click(); 1878 return false; 1879 } 1880 }; 1881 }); 1882}; 1883 1884document.addEventListener("DOMContentLoaded", function () { 1885 loadBoxLinks(); 1886}); 1887 1888// ## link tracking for external links [ 1889(function () { 1890 var excludeList = ["t3-relaunch", "t3-live"]; 1891 var externalLinks = document.querySelectorAll( 1892 'a[href*="://"], a[href^="javascript:linkTo"], a[href^="mailto:"], a[href^="tel:"]' 1893 ); 1894 if (!externalLinks) return; 1895 for (var i = 0, len = externalLinks.length; i < len; i++) { 1896 var addTracking = false; 1897 for (var j = 0, len2 = excludeList.length; j < len2; j++) { 1898 if (externalLinks[i].href.indexOf(excludeList[j]) === -1) { 1899 addTracking = true; 1900 } else { 1901 addTracking = false; 1902 break; 1903 } 1904 } 1905 if (addTracking) { 1906 externalLinks[i].addEventListener("click", function () { 1907 _mtm.push({ event: "externalClick", externalLink: this.href }); 1908 }); 1909 } 1910 } 1911})(); 1912// ## ] 1913 1914// ## faceted search [ 1915(function () { 1916 document.addEventListener("DOMContentLoaded", function () { 1917 var searchFacetesKeywords = document.querySelectorAll(".facet-list-keywords"); 1918 if (!searchFacetesKeywords) return; 1919 for (var i = 0, len = searchFacetesKeywords.length; i < len; i++) { 1920 var optionListKeywords = searchFacetesKeywords[i].querySelectorAll("li.clickable"); 1921 for (var j = 0, len2 = optionListKeywords.length; j < len2; j++) { 1922 // tracking 1923 var valueLabelKeywords = "search" + optionListKeywords[j].dataset.section; 1924 var pushObjKeywords = { event: optionListKeywords[j].dataset.event }; 1925 pushObjKeywords[valueLabelKeywords] = optionListKeywords[j].dataset.facetItemValue; 1926 var clickElKeywords = optionListKeywords[j].querySelector("a"); 1927 clickElKeywords.addEventListener("click", function (e) { 1928 if (e.target.tagName === "A") { 1929 _mtm.push(pushObjKeywords); 1930 } 1931 }); 1932 } 1933 } 1934 1935 var searchFacetesCategories = document.querySelectorAll(".facet-list-categories"); 1936 if (!searchFacetesCategories) return; 1937 for (var i = 0, len = searchFacetesCategories.length; i < len; i++) { 1938 var optionListCategories = searchFacetesCategories[i].querySelectorAll("li.clickable"); 1939 for (var j = 0, len2 = optionListCategories.length; j < len2; j++) { 1940 // tracking 1941 var valueLabelCategories = "search" + optionListCategories[j].dataset.section; 1942 var pushObjCategories = { event: optionListCategories[j].dataset.event }; 1943 pushObjCategories[valueLabelCategories] = optionListCategories[j].dataset.facetItemValue; 1944 var clickElCategories = optionListCategories[j].querySelector("a"); 1945 clickElCategories.addEventListener("click", function (e) { 1946 if (e.target.tagName === "A") { 1947 _mtm.push(pushObjCategories); 1948 } 1949 }); 1950 } 1951 } 1952 1953 }); 1954})(); 1955// ## ] 1956 1957// ## link tracking for internal links [ 1958(function () { 1959 var includeList = ["t3-relaunch", "t3-live", "www.euwid-"]; 1960 var excludeList = ["suche", "search"]; 1961 var internalLinks = document.querySelectorAll("a"); 1962 if (!internalLinks) return; 1963 for (var i = 0, len = internalLinks.length; i < len; i++) { 1964 var addTracking = false;
1965 for (var j = 0, len2 = includeList.length; j < len2; j++) { 1966 if ( 1967 internalLinks[i].href.indexOf(includeList[j]) === -1 && 1968 internalLinks[i].href.indexOf(excludeList[j]) === -1 1969 ) { 1970 addTracking = false; 1971 } else if ( 1972 internalLinks[i].href.indexOf(includeList[j]) >= 0 && 1973 internalLinks[i].href.indexOf(excludeList[j]) === -1 1974 ) { 1975 addTracking = true; 1976 break; 1977 } else { 1978 addTracking = false; 1979 } 1980 } 1981 if (addTracking) { 1982 internalLinks[i].addEventListener("click", function () { 1983 _mtm.push({ event: "internalClick", internalLink: this.href }); 1984 }); 1985 } 1986 } 1987})(); 1988 1989// ## ] 1990 1991function setCookie(c_name, value, exdays) { 1992 var expires = ""; 1993 if (exdays) { 1994 var date = new Date(); 1995 date.setTime(date.getTime() + exdays * 24 * 60 * 60 * 1000); 1996 expires = "; expires=" + date.toUTCString(); 1997 } 1998 document.cookie = c_name + "=" + value + expires + "; path=/; SameSite=None; Secure"; 1999} 2000 2001function getCookie(c_name) { 2002 var c_value = document.cookie; 2003 var c_start = c_value.indexOf(" " + c_name + "="); 2004 if (c_start == -1) { 2005 c_start = c_value.indexOf(c_name + "="); 2006 } 2007 if (c_start == -1) { 2008 c_value = null; 2009 } else { 2010 c_start = c_value.indexOf("=", c_start) + 1; 2011 var c_end = c_value.indexOf(";", c_start); 2012 if (c_end == -1) { 2013 c_end = c_value.length; 2014 } 2015 c_value = unescape(c_value.substring(c_start, c_end)); 2016 } 2017 return c_value; 2018} 2019 2020// ## matomo handling news detail page [ 2021(function () { 2022 if (isIE11) return; 2023 var cc = getCookie("cookie_consent"); 2024 if (!cc) return; 2025 var j = JSON.parse(cc); 2026 if (!j) return; 2027 if (!j.consent) return; 2028 2029 function handle() { 2030 window.lastPage = getCookie("currentPage"); 2031 window.addEventListener("click", function (e) { 2032 setCookie("lastTargetClass", e.target.className, 1); 2033 }); 2034 if (lastPage) { 2035 var lastTargetClass = getCookie("lastTargetClass"); 2036 var path = lastPage.split("/"); 2037 var wasDetail = 2038 path[1] === "news" && 2039 path.length === 5 && 2040 lastPage !== window.location.pathname; 2041 if ( 2042 lastTargetClass && 2043 lastTargetClass.indexOf("navigation__link") === -1 && 2044 wasDetail 2045 ) { 2046 window.addEventListener("load", function () { 2047 _mtm.push({ 2048 event: "browserBackFromNewsDetail", 2049 newsarticleUrl: lastPage, 2050 }); 2051 }); 2052 } 2053 } 2054 setCookie("currentPage", window.location.pathname, 1); 2055 } 2056 2057 handle(); 2058 window.onpagehide = function () {}; 2059})(); 2060// ## ] 2061 2062// ## mobile collapse search filters [ 2063(function () { 2064 var facetGroups = document.querySelectorAll(".facet-group"); 2065 if (!facetGroups.length) return; 2066 facetGroups.forEach(function (el) { 2067 var header = el.querySelector("h5"); 2068 var body = el.querySelector(".facet-list"); 2069 if (!header || !body) return; 2070 header.addEventListener("click", function () { 2071 if (window.innerWidth < 766) { 2072 $(body).slideToggle(); 2073 if (el.classList.contains("initialize")) { 2074 el.classList.remove("initialize"); 2075 } 2076 el.classList.toggle("toggled"); 2077 } 2078 }); 2079 }); 2080})(); 2081// ## ] 2082 2083// ## add id to page [ 2084(function () { 2085 var page = document.querySelector(".page"); 2086 if (page) page.id = "page"; 2087})(); 2088// ## ] 2089 2090// ## ie modal [ 2091(function () { 2092 var ieModal = document.querySelector(".ie-modal"); 2093 if (ieModal && isIE11 && !getCookie("ieModalClosed")) { 2094 ieModal.style.display = "flex"; 2095 } else { 2096 return; 2097 } 2098 var closes = ieModal.querySelectorAll(".close");
2099 closes.forEach(function (close) { 2100 close.addEventListener("click", function () { 2101 ieModal.style.display = "none"; 2102 setCookie("ieModalClosed", true, 1); 2103 }); 2104 }); 2105})(); 2106// ## ] 2107 2108var clickHandler = function (element, event) { 2109 if (event.target.tagName !== "A") { 2110 if (element.dataset.target) { 2111 window.open(element.dataset.href, element.dataset.target); 2112 } else { 2113 window.location.href = element.dataset.href; 2114 } 2115 } 2116}; 2117 2118// ## video played custom event [ 2119(function () { 2120 var vid = document.querySelector('video'); 2121 if (!vid) return; 2122 vid.addEventListener('play', function() { 2123 var _mtm = window._mtm || []; 2124 _mtm.push({'event': 'videoPlayed'}); 2125 }, { once: true }); 2126})(); 2127// ## ] 2128 2129function allowExternalService(service) { 2130 function getCookie(name) { 2131 let cookies = document.cookie.split("; "); 2132 for (let i = 0; i < cookies.length; i++) { 2133 let cookie = cookies[i].split("="); 2134 if (cookie[0] === name) { 2135 return cookie[1]; 2136 } 2137 } 2138 return null; 2139 } 2140 2141 function updateCookie(name, value, path = "/", sameSite = "Strict") { 2142 document.cookie = `${name}=${value}; path=${path}; SameSite=${sameSite}`; 2143 } 2144 2145 const cookieName = 'cookie_consent' 2146 let cc = getCookie(cookieName); 2147 if (cc) cc = decodeURIComponent(cc); 2148 if (cc) cc = JSON.parse(cc); 2149 2150 if (!cc) return; 2151 cc.options.push(service); 2152 updateCookie(cookieName, encodeURIComponent(JSON.stringify(cc))); 2153 location.reload(); 2154} 2155 2156window.allowExternalService = allowExternalService; 2157 2158// ## consent based iframes [ 2159(() => { 2160 const lang = document.documentElement.getAttribute("lang"); 2161 2162 function loadScript(script, callback) { 2163 const sn = document.createElement('script'); 2164 sn.src = script; 2165 if (callback) { 2166 sn.onload = callback; 2167 } 2168 document.head.appendChild(sn); 2169 } 2170 2171 function addSrc(nodes, src) { 2172 nodes.forEach(n => { 2173 n.src = src; 2174 }); 2175 } 2176 2177 function showBanner(nodes, bannerContent) { 2178 nodes.forEach(node => { 2179 if (node.tagName === "SCRIPT") { 2180 node.parentNode.outerHTML = bannerContent; 2181 } else { 2182 node.outerHTML = bannerContent; 2183 } 2184 }); 2185 } 2186 2187 function loadWithConsent(args) { 2188 // string?, function?, string?, function, dom node[]?, string (html)? 2189 const { script, scriptCallback, src, checkConsent, nodes, bannerContent } = args; 2190 if (typeof checkConsent !== 'function') { 2191 let err = 'Error in loadWithConsent: ' 2192 + '`checkConsent` has to be a function.'; 2193 console.error(err); 2194 return; 2195 } 2196 2197 if (checkConsent()) { 2198 // use script for loading scripts. e.g. maps 2199 if (script) { 2200 loadScript(script, scriptCallback); 2201 } 2202 // use src, to add a src attribute to a tag. e.g. an iframe 2203 if (src) { 2204 addSrc(nodes, src); 2205 } 2206 } else { 2207 if (nodes.length && bannerContent) { 2208 showBanner(nodes, bannerContent); 2209 } 2210 } 2211 } 2212 2213 const iframes = document.querySelectorAll('iframe[consent-src], script[consent-src]'); 2214 if (!iframes.length) return; 2215 2216 function getCookieValue(cookieName) { 2217 const cookies = document.cookie.split(';'); 2218 for (let i = 0; i < cookies.length; i++) { 2219 const cookie = cookies[i].trim(); 2220 if (cookie.startsWith(cookieName + '=')) { 2221 return decodeURIComponent(cookie.substring(cookieName.length + 1)); 2222 } 2223 } 2224 return null; 2225 } 2226 2227 function getOptions() { 2228 let c = getCookieValue('cookie_consent'); 2229 if (!c) return false; 2230 c = JSON.parse(c); 2231 const options = c.options 2232 if (!options) return false; 2233 return options; 2234 } 2235 2236 function check(service) { 2237 const options = getOptions(); 2238 if (!options) return false;
2239 return options.find(el => el === service); 2240 } 2241 2242 function escapeHtml(value) { 2243 const el = document.createElement('div'); 2244 el.textContent = value; 2245 return el.innerHTML; 2246 } 2247 2248 // customText stammt aus dem Attribut consent-text der Einbettung und ersetzt nur den 2249 // einleitenden Satz - der Verweis auf die Datenschutzerklaerung bleibt in jedem Fall stehen. 2250 function makeConsentInner(service, customText) { 2251 const intro = customText ? escapeHtml(customText) : null; 2252 if (lang === "de") { 2253 return ` 2254 <div>${intro || `Um diesen externen Inhalt von ${service} anzuzeigen, benötigen wir Ihre Zustimmung.`}<br>Informationen, wie dieser Dienst Ihre Daten verarbeitet, finden Sie in unserer <a target="_blank" href="/datenschutz">Datenschutzerklärung</a>.</div> 2255 <div onclick="allowExternalService('${service}')" class="button button--round">${service} erlauben</div>` 2256 } else { 2257 return ` 2258 <div>${intro || `In order to display this ${service} external content we need your consent.`}<br>For information on how this platform processes your data, please see our <a target="_blank" href="/privacy-policy">privacy policy</a>.</div> 2259 <div onclick="allowExternalService('${service}')" class="button button--round">Allow ${service} content</div>` 2260 } 2261 } 2262 2263 iframes.forEach(iframe => { 2264 const src = iframe.getAttribute('consent-src'); 2265 let service; 2266 if (src.includes('youtube.com') || src.includes('youtube-nocookie.com')) { 2267 service = 'YouTube'; 2268 } 2269 // Embeds laufen weiter ueber platform.twitter.com, Permalinks ueber x.com; der 2270 // Dienstname muss exakt dem Identifier des Backend-Eintrags entsprechen. 2271 if (src.includes('twitter.com') || /\/\/([^\/]*\.)?x\.com([\/:?#]|$)/.test(src)) { 2272 service = 'X'; 2273 } 2274 if (src.includes('podigee')) { 2275 service = 'Podigee'; 2276 } 2277 if (src.includes('linkedin.com')) { 2278 service = 'LinkedIn'; 2279 } 2280 // Podcast-Anbieter seit 2026, loest Podigee ab. Der Player laeuft unter 2281 // player.rss.com, Folgenlinks unter rss.com - beide deckt die Pruefung ab. 2282 if (src.includes('rss.com')) { 2283 service = 'RSS.com'; 2284 } 2285 const args = { 2286 src: src, 2287 checkConsent: () => { 2288 return check(service) 2289 }, 2290 nodes: [iframe], 2291 bannerContent: ` 2292 <style> 2293 .external-consent-banner { 2294 padding: 30px; 2295 background: lightgray; 2296 display: flex; 2297 flex-direction: column; 2298 align-items: center; 2299 gap: 15px; 2300 text-align: center; 2301 } 2302 .external-consent-banner span { 2303 text-decoration: underline; 2304 } 2305 </style> 2306 <div class="external-consent-banner"> 2307 ${makeConsentInner(service, iframe.getAttribute('consent-text'))} 2308 </div> 2309 ` 2310 }; 2311 2312 loadWithConsent(args); 2313 }); 2314})(); 2315// ## ] 2316 2317 2318 2319// Wartet, bis alle noch per AJAX nachladenden Bereiche (z.B. #market_report, siehe 2320// requestDataWithJson() in euwid_markets.js, das per .classList.add('loading') markiert 2321// und erst im xhr.onload wieder entfernt) fertig sind, bevor der PDF-Snapshot gemacht 2322// wird. Ohne das griff generatePdfOnClick() bei click kurz nach Tab-/Perioden-Wechsel 2323// in einen leeren Container (lokal in DDEV nicht sichtbar, da dort die Anfrage quasi 2324// sofort durch ist - auf Prod mit echter Netzwerklatenz blieb der Marktbericht im PDF 2325// dadurch leer, siehe Asana 1216553301537360). 2326function waitForPendingAjaxContent(root, timeoutMs) { 2327 return new Promise((resolve) => { 2328 const deadline = Date.now() + timeoutMs; 2329 (function poll() { 2330 if (!root.querySelector('.loading') || Date.now() >= deadline) { 2331 resolve(); 2332 return; 2333 } 2334 setTimeout(poll, 200); 2335 })(); 2336 }); 2337} 2338 2339async function generatePdfOnClick(event, clickedButton) { 2340 event.preventDefault(); 2341 2342 const pdfUrl = '/?type=1756466055'; 2343 // Body-Klasse "landingpage" ist nicht auf allen Diensten gesetzt (z.B. PZ/VP fehlt sie, 2344 // RE hat sie) -> ohne Fallback war querySelector null und der Download brach ab. 2345 // Der PDF-Controller verpackt ohnehin nur das innere Body-HTML, daher ist document.body 2346 // verhaltensgleich zu body.landingpage. 2347 const contentEl = document.querySelector('body.landingpage') || document.body; 2348 2349 clickedButton.classList.add('is-loading'); 2350 await waitForPendingAjaxContent(contentEl, 8000); 2351 2352 // Readonly-Felder wie #startDateSmall/#endDateSmall (Betrachtungszeitraum) zeigen 2353 // ihren Wert nur als per JS gesetzte .value-Property an - das value-Attribut im 2354 // Markup bleibt "". innerHTML serialisiert nur das Attribut, im PDF-Export (reiner 2355 // HTML-Snapshot) stand der Zeitraum dadurch leer. Vor dem Snapshot synchronisieren. 2356 contentEl.querySelectorAll('input[readonly]').forEach((input) => { 2357 input.setAttribute('value', input.value); 2358 }); 2359 2360 // Marktbericht- (id=3) und Preisspiegel-Tab (id=1) isoliert im Snapshot verschicken 2361 // statt der kompletten Seite: ein bislang nicht abschliessend identifizierter 2362 // Chromium-Print-Bug (headless, --disable-gpu im PDF-Render-Dienst) laesst Inhalt
2363 // (Berichtstext bzw. Fussnoten der Preisspiegel-Tabelle) ersatzlos verschwinden, 2364 // sobald die anderen Markt-Tabs mit im Snapshot stecken - fuer den Marktbericht-Tab 2365 // reproduzierbar nachgewiesen, Ursache trotz ausfuehrlicher Bisektion nicht 2366 // abschliessend gefunden (Asana 1216553301537360). Preisentwicklung-Tab (id=2) war 2367 // davon nicht betroffen, bleibt daher unangetastet beim bisherigen 2368 // Vollseiten-Snapshot; News-Downloads haben ohnehin kein data-tab-content-id. 2369 const isolatedTab = clickedButton.closest('[data-tab-content-id="1"], [data-tab-content-id="3"]'); 2370 let mainContent; 2371 if (isolatedTab) { 2372 // Viele CSS-Regeln (Tabellenspalten, Legende) verlangen einen ".markets"-Vorfahren 2373 // (normalerweise #market selbst) - der fehlt, wenn nur der Tab-Container isoliert 2374 // verschickt wird. Klasse auf einer Kopie ergaenzen (nicht am Original, um die 2375 // sichtbare Seite nicht zu veraendern), nicht den kompletten #market-Wrapper 2376 // wiederherstellen, da der vermutlich Teil des urspruenglichen Bugs war. 2377 const clone = isolatedTab.cloneNode(true); 2378 clone.classList.add('markets'); 2379 // Der Markttitel steht in .market-nav ausserhalb der Tab-Container und fehlte 2380 // dadurch im isolierten Snapshot (Preisspiegel-Tab; der Marktbericht-Tab bringt 2381 // eine eigene Ueberschrift mit, daher nur ergaenzen, wenn keine vorhanden ist). 2382 const marketHeadline = document.querySelector('h1.headline-markets'); 2383 if (marketHeadline && !clone.querySelector('h1')) { 2384 const headlineTarget = clone.querySelector('.container') || clone; 2385 headlineTarget.insertBefore(marketHeadline.cloneNode(true), headlineTarget.firstChild); 2386 } 2387 mainContent = clone.outerHTML; 2388 } else { 2389 // Preisentwicklung-Tab (id=2): unbelegte Vergleichssorte-Spalten (leerer 2390 // "Vergleichssorte auswaehlen"-Platzhalter, im statischen PDF nicht anklickbar 2391 // und daher sinnlos, siehe Asana 1217080039338118) vor dem Snapshot entfernen - 2392 // auf einer Kopie statt am Original, damit die sichtbare Seite unveraendert 2393 // bleibt. cloneNode(true) uebernimmt bei <select> den aktuellen Wert (nicht nur 2394 // das statische "selected"-Attribut), select.value ist daher auch auf der Kopie 2395 // zuverlaessig. 2396 const clone = contentEl.cloneNode(true); 2397 clone.querySelectorAll('select.additional__grades').forEach((select) => { 2398 if (!select.value) { 2399 const column = select.closest('.table-column.table-select'); 2400 if (column) { 2401 column.remove(); 2402 } 2403 } 2404 }); 2405 mainContent = clone.innerHTML; 2406 } 2407 const encodedHtml = encodeURIComponent(mainContent); 2408 const pageTitle = document.title; 2409 const headerHtml = document.querySelector('.logo') ? document.querySelector('.logo').outerHTML : ''; 2410 const baseUrl = window.location.origin; 2411 2412 const formData = new FormData(); 2413 formData.append('tx_themeeuwid_themeeuwid[action]', 'generatePdf'); 2414 formData.append('tx_themeeuwid_themeeuwid[pdf_html_content]', encodedHtml); 2415 formData.append('tx_themeeuwid_themeeuwid[page_title]', pageTitle); 2416 formData.append('tx_themeeuwid_themeeuwid[header_html]', encodeURIComponent(headerHtml)); 2417 formData.append('tx_themeeuwid_themeeuwid[base_url]', baseUrl); 2418 2419 // Fetch-API verwenden, um das PDF anzufordern 2420 fetch(pdfUrl, { 2421 method: 'POST', 2422 body: formData 2423 }) 2424 .then(response => { 2425 if (!response.ok) { 2426 throw new Error('Netzwerk-Antwort war nicht OK.'); 2427 } 2428 return response.blob(); 2429 }) 2430 .then(blob => { 2431 const url = window.URL.createObjectURL(blob); 2432 const a = document.createElement('a'); 2433 const safeFilename = pageTitle.replace(/[^a-z0-9\u00C0-\u017F]/gi, '_').toLowerCase(); 2434 a.style.display = 'none'; 2435 a.href = url; 2436 a.download = `${safeFilename}.pdf`; 2437 document.body.appendChild(a); 2438 a.click(); 2439 2440 // Aufräumen 2441 window.URL.revokeObjectURL(url); 2442 document.body.removeChild(a); 2443 }) 2444 .catch(error => { 2445 console.error('Fehler beim Erstellen des PDFs:', error); 2446 }) 2447 .finally(() => { 2448 clickedButton.classList.remove('is-loading'); 2449 }); 2450};
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.