PageSourceSearch

https://www.msgfood.solutions/.resources/msg-main-theme/webresources/js/navigation-teasers.js

js msgfood.solutions collected 2026-10-10 02:36:04 UTC 7,112 bytes, 207 lines download raw bytes

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.