PageSourceSearch

https://jameskrw.github.io/javascript/news.js

js jameskrw.github.io collected 2026-10-03 09:21:55 UTC 2,889 bytes, 101 lines download raw bytes

1(function () {
2  const data = Array.isArray(window.NEWS_ITEMS) ? window.NEWS_ITEMS : [];
3  const VISIBLE_COUNT = 4;
4
5  function renderNews() {
6    const carousel = document.querySelector('[data-news-carousel]');
7    const track = document.querySelector('[data-news-track]');
8
9    if (!carousel || !track) {
10      return;
11    }
12
13    track.innerHTML = '';
14
15    if (!data.length) {
16      const empty = document.createElement('p');
17      empty.className = 'news-empty';
18      empty.textContent = 'No news yet — stay tuned!';
19      track.appendChild(empty);
20      return;
21    }
22
23    data.forEach((item) => {
24      const row = document.createElement('article');
25      row.className = 'news-item';
26      row.dataset.newsId = item.id;
27
28      const emoji = document.createElement('span');
29      emoji.className = 'news-emoji';
30      emoji.textContent = item.emoji || '🗞️';
31      row.appendChild(emoji);
32
33      const text = document.createElement('span');
34      text.className = 'news-text';
35      text.innerHTML = `<strong>${item.dateLabel}:</strong> ${item.contentHtml}`;
36      row.appendChild(text);
37
38      track.appendChild(row);
39    });
40
41    carousel.dataset.visibleCount = String(VISIBLE_COUNT);
42    carousel.style.setProperty('--visible-count', VISIBLE_COUNT);
43    enableVerticalDrag(carousel);
44  }
45
46  function enableVerticalDrag(container) {
47    if (container.dataset.dragEnabled === 'true') {
48      return;
49    }
50    container.dataset.dragEnabled = 'true';
51
52    let pointerActive = false;
53    let startY = 0;
54    let startScroll = 0;
55
56    const onPointerDown = (event) => {
57      if (event.pointerType === 'mouse' && event.button !== 0) {
58        return;
59      }
60      pointerActive = true;
61      startY = event.clientY;
62      startScroll = container.scrollTop;
63      container.classList.add('news-dragging');
64      if (container.setPointerCapture) {
65        container.setPointerCapture(event.pointerId);
66      }
67    };
68
69    const onPointerMove = (event) => {
70      if (!pointerActive) {
71        return;
72      }
73      const delta = event.clientY - startY;
74      container.scrollTop = startScroll - delta;
75      event.preventDefault();
76    };
77
78    const onPointerUp = (event) => {
79      if (!pointerActive) {
80        return;
81      }
82      pointerActive = false;
83      container.classList.remove('news-dragging');
84      if (container.releasePointerCapture) {
85        try {
86          container.releasePointerCapture(event.pointerId);
87        } catch (error) {
88          /* ignore */
89        }
90      }
91    };
92
93    container.addEventListener('pointerdown', onPointerDown);
94    container.addEventListener('pointermove', onPointerMove);
95    container.addEventListener('pointerup', onPointerUp);
96    container.addEventListener('pointercancel', onPointerUp);
97    container.addEventListener('pointerleave', onPointerUp);
98  }
99
100  document.addEventListener('DOMContentLoaded', renderNews);
101})();

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.