PageSourceSearch

https://www.onalert.gr/app/themes/onalert/js/categorized-feed.js?ver=1782737010

js onalert.gr collected 2026-10-02 12:09:26 UTC 11,964 bytes, 273 lines download raw bytes

1(function() {
2    document.addEventListener('DOMContentLoaded', function() {
3        const MAX_POSTS_TO_SHOW = 5;
4        const tagLinks = document.querySelectorAll('a.tag-list__link');
5        const feedCache = new Map();
6
7        // Target the specific article container
8        const container = document.querySelector('.grid__content.article-list') || document.querySelector('.grid__content');
9
10        let initialArticleHTMLs = [];
11        let cardTemplate = null;
12
13        if (container) {
14            const initialCards = container.querySelectorAll('article.content-card');
15            initialCards.forEach(card => {
16                initialArticleHTMLs.push(card.outerHTML);
17            });
18            const firstCard = container.querySelector('article.content-card');
19            if (firstCard) {
20                cardTemplate = firstCard.cloneNode(true);
21            }
22            const tplRibbon = cardTemplate ? cardTemplate.querySelector('.content-card__ribbon') : null;
23            if (tplRibbon) tplRibbon.remove();
24        }
25
26        // Create "ΟΛΑ" button and set it as ACTIVE by default
27        const allLink = document.createElement('a');
28        allLink.href = '#';
29        allLink.className = 'tag-list__link tag-list__link--is-active';
30        allLink.innerText = 'ΟΛΑ';
31
32        // Find the tag list INSIDE the specific container
33        const oldTagList = container ? container.querySelector('.tag-list') : document.querySelector('.tag-list');
34
35        // Create <li> wrapper
36        const allLi = document.createElement('li');
37        allLi.className = 'tag-list__item';
38
39        // Put <a> inside the <li>
40        allLi.appendChild(allLink);
41
42        // Inject the full <li> at the start of the <ul>
43        if (oldTagList) {
44            oldTagList.prepend(allLi);
45        } else if (tagLinks.length > 0) {
46            tagLinks[0].parentNode.parentNode.prepend(allLi);
47        }
48
49        function getTermRequest(link) {
50            const taxonomy = link.dataset.taxonomy || '';
51            const termId = link.dataset.termId || '';
52
53            return {
54                taxonomy,
55                queryParam: taxonomy,
56                termId
57            };
58        }
59
60        function detachCurrentCards() {
61            container.querySelectorAll('article.content-card').forEach(card => card.remove());
62        }
63
64        function insertCard(card, readMoreLink) {
65            if (readMoreLink && readMoreLink.parentNode) {
66                readMoreLink.parentNode.insertBefore(card, readMoreLink);
67            } else {
68                container.appendChild(card);
69            }
70        }
71
72        function insertCachedCards(cards, readMoreLink) {
73            detachCurrentCards();
74            cards.forEach(card => insertCard(card, readMoreLink));
75        }
76
77        function pickPreviewImage(imageSizes, imgEl) {
78            const sizes = Object.values(imageSizes)
79                .filter(size => size.source_url && size.width)
80                .sort((a, b) => a.width - b.width);
81            const targetWidth = Math.ceil(imgEl.getBoundingClientRect().width || imgEl.clientWidth || 330);
82
83            return sizes.find(size => size.width >= targetWidth) || sizes[sizes.length - 1] || null;
84        }
85
86        function updateRibbon(card, topic) {
87            const labels = {
88                exclusive: 'ΑΠΟΚΛΕΙΣΤΙΚΟ',
89                interview: 'ΣΥΝΕΝΤΕΥΞΗ',
90                report: 'ΡΕΠΟΡΤΑΖ'
91            };
92            const imgContainer = card.querySelector('.content-card__img-container');
93            const existingRibbon = card.querySelector('.content-card__ribbon');
94
95            if (!labels[topic]) {
96                if (existingRibbon) existingRibbon.remove();
97                return;
98            }
99
100            const ribbon = existingRibbon || document.createElement('span');
101            ribbon.className = 'content-card__ribbon';
102            ribbon.innerText = labels[topic];
103            if (!existingRibbon && imgContainer) {
104                imgContainer.prepend(ribbon);
105            }
106        }
107
108        allLink.addEventListener('click', function(e) {
109            e.preventDefault();
110
111            if (container) {
112                container.querySelectorAll('.tag-list__link').forEach(l => l.classList.remove('tag-list__link--is-active'));
113                this.classList.add('tag-list__link--is-active');
114
115                const readMoreAnchor = container.querySelector('.read-more-link a, a.read-more-link');
116                if (readMoreAnchor) {
117                    readMoreAnchor.href = '/eidiseis-tora/';
118                }
119            }
120
121            if (container && initialArticleHTMLs.length > 0) {
122                const readMoreLink = container.querySelector('.read-more-link');
123
124                let currentCards = container.querySelectorAll('article.content-card');
125                currentCards.forEach(card => card.remove());
126
127                initialArticleHTMLs.forEach(htmlString => {
128                    const tempDiv = document.createElement('div');
129                    tempDiv.innerHTML = htmlString;
130                    const restoredCard = tempDiv.firstElementChild;
131                    if (restoredCard) {
132                        if (readMoreLink && readMoreLink.parentNode) {
133                            readMoreLink.parentNode.insertBefore(restoredCard, readMoreLink);
134                        } else {
135                            container.appendChild(restoredCard);
136                        }
137                    }
138                });
139            }
140        });
141
142        tagLinks.forEach(link => {
143            link.addEventListener('click', async function(e) {
144                e.preventDefault();
145
146                if (container) {
147                    container.querySelectorAll('.tag-list__link').forEach(l => l.classList.remove('tag-list__link--is-active'));
148                    this.classList.add('tag-list__link--is-active');
149
150                    const readMoreAnchor = container.querySelector('.read-more-link a, a.read-more-link');
151                    if (readMoreAnchor) {
152                        readMoreAnchor.href = this.href;
153                    }
154                }
155
156                const { taxonomy, queryParam, termId } = getTermRequest(this);
157
158                if (!container) return;
159
160                if (!taxonomy || !termId) return;
161
162                try {
163                    const cacheKey = `${taxonomy}:${termId}`;
164                    const readMoreLink = container.querySelector('.read-more-link');
165                    const cachedCards = feedCache.get(cacheKey);
166                    if (cachedCards) {
167                        insertCachedCards(cachedCards, readMoreLink);
168                        return;
169                    }
170
171                    const postRes = await fetch(`/wp-json/wp/v2/posts?${queryParam}=${termId}&per_page=${MAX_POSTS_TO_SHOW}&_embed`);
172                    const posts = await postRes.json();
173
174                    detachCurrentCards();
175
176                    for (let i = 0; i < posts.length && i < MAX_POSTS_TO_SHOW; i++) {
177                        const post = posts[i];
178                        const feedCard = post.wrt_feed_card || {};
179                        let card;
180
181                        if (cardTemplate) {
182                            card = cardTemplate.cloneNode(true);
183                        } else {
184                            console.warn('No template card found to clone. Cannot display posts.');
185                            break;
186                        }
187                        const titleEl = card.querySelector('.content-card__content__title a');
188                        const excerptEl = card.querySelector('.content-card__content__description');
189                        const topicEl = card.querySelector('.content-card__content__topic');
190                        const postLinkEls = card.querySelectorAll(
191                            '.content-card__image, .content-card__content__title a'
192                        );
193                        const linkEls = card.querySelectorAll('a');
194                        const imgEl = card.querySelector('img');
195                        const timeEl = card.querySelector('time');
196                        const metaEl = card.querySelector('.meta');
197                        const pictureSources = card.querySelectorAll('picture source');
198                        pictureSources.forEach(s => s.remove());
199                        if (imgEl) {
200                            imgEl.removeAttribute('src');
201                            imgEl.removeAttribute('srcset');
202                        }
203
204                        if (titleEl) {
205                            titleEl.innerHTML = feedCard.title_html || post.title.rendered;
206                            titleEl.href = post.link;
207                        }
208
209                        postLinkEls.forEach(l => l.href = post.link);
210
211                        linkEls.forEach(l => l.href = post.link);
212                        updateRibbon(card, post.meta_box && post.meta_box.post_topic ? post.meta_box.post_topic : null);
213
214                        if (imgEl && post._embedded && post._embedded['wp:featuredmedia']) {
215                            const media = post._embedded['wp:featuredmedia'][0];
216
217                            const imageSizes = media.media_details && media.media_details.sizes ? media.media_details.sizes : {};
218                            const sourceUrl = media.source_url;
219                            const previewImage = pickPreviewImage(imageSizes, imgEl);
220                            const previewUrl = previewImage && previewImage.source_url ? previewImage.source_url : sourceUrl;
221
222                            const jpegSrcset = [];
223
224                            jpegSrcset.push(`${sourceUrl} ${media.media_details?.width || 1440}w`);
225
226                            Object.values(imageSizes).forEach(size => {
227                                if (size.source_url) {
228                                    jpegSrcset.push(`${size.source_url} ${size.width}w`);
229                                }
230                            });
231
232                            imgEl.srcset = jpegSrcset.join(', ');
233                            imgEl.src = previewUrl;
234                        }
235
236                        if (excerptEl) {
237                            excerptEl.textContent = feedCard.summary || '';
238                        }
239
240                        if (topicEl){
241                            topicEl.innerText = feedCard.topic_name || this.innerText;
242                            topicEl.href = feedCard.topic_url || this.href;
243                        }
244
245                        if (metaEl && feedCard.date_html) {
246                            const tempDiv = document.createElement('div');
247                            tempDiv.innerHTML = feedCard.date_html;
248                            const renderedMeta = tempDiv.firstElementChild;
249
250                            if (renderedMeta) {
251                                metaEl.replaceWith(renderedMeta);
252                            }
253                        } else if (timeEl) {
254                            const date = new Date(post.date);
255                            const datePart = date.toLocaleDateString('el-GR', { day: 'numeric', month: 'short', year: 'numeric' }).toUpperCase();
256                            const timePart = date.toLocaleTimeString('el-GR', { hour: '2-digit', minute: '2-digit' });
257                            timeEl.innerText = `${datePart}, ${timePart}`;
258                            timeEl.setAttribute('datetime', post.date);
259                        }
260
261                        card.style.display = 'block';
262                        insertCard(card, readMoreLink);
263                    }
264
265                    feedCache.set(cacheKey, Array.from(container.querySelectorAll('article.content-card')));
266
267                } catch (err) {
268                    console.error('Error updating content cards:', err);
269                }
270            });
271        });
272    });
273})();

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.