1(function () { 2 "use strict"; 3 4 if (window.msgNavigationTeasers) { 5 if (window.msgComponentLifecycle) { 6 window.msgComponentLifecycle.scan(document); 7 } 8 return; 9 } 10 11 const requests = new Map(); 12 const preloadedImageSources = window.msgNavigationTeaserPreloadedImages || new Set(); 13 window.msgNavigationTeaserPreloadedImages = preloadedImageSources; 14 15 function setLinkAttributes(element, link) { 16 Object.keys(link || {}).forEach(function (key) { 17 element.setAttribute("link-" + key, link[key] || ""); 18 }); 19 } 20 21 function imageSrc(item, resourcePath) { 22 return item.image && item.image.src ? item.image.src : resourcePath + "/images/default.jpg"; 23 } 24 25 function preloadImage(src) { 26 if (!src || preloadedImageSources.has(src)) { 27 return; 28 } 29 preloadedImageSources.add(src); 30 const image = new Image(); 31 image.decoding = "async"; 32 image.src = src; 33 } 34 35 function preloadTeaserImages(items) { 36 (items || []).forEach(function (item) { 37 preloadImage(item.image && item.image.src ? item.image.src : ""); 38 }); 39 } 40 41 function imageSlot(item, resourcePath) { 42 const slot = document.createElement("div"); 43 slot.setAttribute("slot", "image"); 44 const image = document.createElement("img"); 45 image.loading = "eager"; 46 image.decoding = "async"; 47 image.src = imageSrc(item, resourcePath); 48 image.alt = item.image && item.image.alt ? item.image.alt : ""; 49 slot.appendChild(image); 50 return slot; 51 } 52 53 function textSlot(item) { 54 const slot = document.createElement("p"); 55 slot.setAttribute("slot", "text"); 56 slot.innerHTML = item.text || ""; 57 return slot; 58 } 59 60 function createFeaturedTeaser(item, resourcePath) { 61 const wrapper = document.createElement("div"); 62 wrapper.className = "topic-item feature-item"; 63 const teaser = document.createElement("msg-teaser-featured"); 64 teaser.setAttribute("headline", item.title || ""); 65 teaser.setAttribute("category", item.category || ""); 66 setLinkAttributes(teaser, item.link); 67 teaser.appendChild(imageSlot(item, resourcePath)); 68 teaser.appendChild(textSlot(item)); 69 wrapper.appendChild(teaser); 70 return wrapper; 71 } 72 73 function createImageTeasers(items, resourcePath) { 74 const wrapper = document.createElement("div"); 75 wrapper.className = "topic-item teaser-item"; 76 items.forEach(function (item) { 77 const teaser = document.createElement("msg-teaser-image"); 78 teaser.setAttribute("headline", item.title || ""); 79 setLinkAttributes(teaser, item.link); 80 teaser.appendChild(imageSlot(item, resourcePath)); 81 wrapper.appendChild(teaser); 82 }); 83 return wrapper; 84 } 85 86 function createTextTeaser(item) { 87 const wrapper = document.createElement("div"); 88 wrapper.className = "topic-item"; 89 const teaser = document.createElement("msg-teaser-text"); 90 teaser.setAttribute("headline", item.title || ""); 91 setLinkAttributes(teaser, item.link); 92 teaser.appendChild(textSlot(item)); 93 wrapper.appendChild(teaser); 94 return wrapper; 95 } 96 97 function render(root, container, items) { 98 container.replaceChildren(); 99 if (!items || items.length === 0) { 100 return; 101 } 102 const resourcePath = root.dataset.resourcePath || "/.resources/msg-main-theme/webresources"; 103 container.appendChild(createFeaturedTeaser(items[0], resourcePath)); 104 if (items.length >= 2) { 105 container.appendChild(createImageTeasers(items.slice(1, 4), resourcePath)); 106 } 107 if (items.length >= 5) { 108 container.appendChild(createTextTeaser(items[4])); 109 } 110 } 111 112 function requestNavigationTeasers(endpoint, site, locale) { 113 const key = endpoint + "|" + site + "|" + locale; 114 if (requests.has(key)) { 115 return requests.get(key); 116 } 117 118 const params = new URLSearchParams({site: site, locale: locale}); 119 const request = fetch(endpoint + "?" + params.toString(), { 120 method: "GET", 121 credentials: "same-origin", 122 headers: { 123 "Accept": "application/json", 124 "X-Requested-With": "XMLHttpRequest" 125 } 126 }).then(function (response) { 127 if (!response.ok) { 128 throw new Error("navigationTeasers request failed with status " + response.status); 129 } 130 return response.json(); 131 }).then(function (data) { 132 Object.keys(data || {}
132).forEach(function (pageId) { 133 preloadTeaserImages(data[pageId]); 134 }); 135 return data || {}; 136 }); 137 138 requests.set(key, request); 139 request.then(function () { 140 requests.delete(key); 141 }, function () { 142 requests.delete(key); 143 }); 144 return request; 145 } 146 147 function initNavigationTeasers(root) { 148 const container = root.querySelector("[data-navigation-teasers-items]"); 149 if (!container) { 150 return; 151 } 152 const endpoint = root.dataset.navigationTeasersEndpoint || 153 "/.rest/components/newsList/navigationTeasers"; 154 const site = root.dataset.site || ""; 155 const locale = root.dataset.locale || ""; 156 const pageId = root.dataset.pageId || ""; 157 let active = true; 158 159 function isCurrent() { 160 return active && root.isConnected !== false && 161 root.querySelector("[data-navigation-teasers-items]") === container; 162 } 163 164 if (!site || !locale || !pageId) { 165 render(root, container, []); 166 return function cleanupEmptyNavigationTeasers() { 167 active = false; 168 }; 169 } 170 171 requestNavigationTeasers(endpoint, site, locale).then(function (itemsByPageId) { 172 if (isCurrent()) { 173 render(root, container, itemsByPageId[pageId] || []); 174 } 175 }).catch(function (error) { 176 console.error("navigationTeasers request failed for " + endpoint + ".", error); 177 if (isCurrent()) { 178 render(root, container, []); 179 } 180 }); 181 182 return function cleanupNavigationTeasers() { 183 active = false; 184 }; 185 } 186 187 const lifecycle = window.msgComponentLifecycle; 188 if (!lifecycle) { 189 console.error("msgComponentLifecycle is required for navigationTeasers."); 190 return; 191 } 192 193 lifecycle.register({ 194 name: "navigationTeasers", 195 selector: "[data-navigation-teasers]", 196 anchors: function (root) { 197 return [root.querySelector("[data-navigation-teasers-items]")]; 198 }, 199 init: initNavigationTeasers 200 }); 201 202 window.msgNavigationTeasers = { 203 init: function (root) { 204 lifecycle.scan(root || document); 205 } 206 }; 207})();
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.