PageSourceSearch

https://wirres.net/assets/js/isso-summary.6f445c5237db23700885a5922449e4a9.js

js wirres.net collected 2026-09-24 19:02:06 UTC 8,045 bytes, 339 lines download raw bytes

1(function () {
2  function formatSummaryLabel(count) {
3    var n = Math.max(0, parseInt(count, 10) || 0);
4
5    if (n <= 0) {
6      return 'kommentare';
7    }
8
9    if (n === 1) {
10      return '1 kommentar';
11    }
12
13    return n + ' kommentare';
14  }
15
16  function getIssoHost() {
17    var script = document.querySelector('script[data-isso][src*="embed"]');
18
19    return script && script.dataset.isso ? script.dataset.isso.replace(/\/$/, '') : null;
20  }
21
22  function readFederatedCountAttr(el) {
23    if (!el) {
24      return null;
25    }
26
27    return el.getAttribute('data-federated-count');
28  }
29
30  function readCountAttr(el, name) {
31    if (!el) {
32      return null;
33    }
34
35    return el.getAttribute(name);
36  }
37
38  function getInstagramCommentCount(summary, thread) {
39    if (thread && typeof thread._wirresInstagramCount === 'number') {
40      return thread._wirresInstagramCount;
41    }
42
43    var raw = readCountAttr(thread, 'data-instagram-count')
44      || readCountAttr(summary, 'data-instagram-count')
45      || '0';
46
47    return Math.max(0, parseInt(raw, 10) || 0);
48  }
49
50  function getAddonCommentCount(summary, thread) {
51    return getFederatedCommentCount(summary, thread) + getInstagramCommentCount(summary, thread);
52  }
53
54  function getFederatedCommentCount(summary, thread) {
55    if (thread && typeof thread._wirresFederatedCount === 'number') {
56      return thread._wirresFederatedCount;
57    }
58
59    var raw = readFederatedCountAttr(thread)
60      || readFederatedCountAttr(summary)
61      || '0';
62
63    return Math.max(0, parseInt(raw, 10) || 0);
64  }
65
66  function countIssoCommentsInDom(thread) {
67    var root = thread.querySelector('#isso-root');
68
69    if (!root) {
70      return 0;
71    }
72
73    return root.querySelectorAll('.isso-comment').length;
74  }
75
76  function applySummaryTotal(summary, thread, issoCount) {
77    var addonCount = getAddonCommentCount(summary, thread);
78
79    summary.textContent = formatSummaryLabel(
80      Math.max(0, parseInt(issoCount, 10) || 0) + addonCount
81    );
82  }
83
84  function refreshIssoSummary() {
85    var summary = document.querySelector('[data-isso-summary]');
86    var thread = document.getElementById('isso-thread');
87    var host = getIssoHost();
88
89    if (!summary || !thread) {
90      return;
91    }
92
93    var threadId = summary.dataset.threadId || thread.dataset.issoId;
94
95    if (!threadId || !host) {
96      applySummaryTotal(summary, thread, countIssoCommentsInDom(thread));
97      return;
98    }
99
100    fetch(host + '/count', {
101      method: 'POST',
102      headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
103      body: JSON.stringify([threadId]),
104    })
105      .then(function (response) {
106        return response.ok ? response.json() : null;
107      })
108      .then(function (counts) {
109        if (!Array.isArray(counts)) {
110          applySummaryTotal(summary, thread, countIssoCommentsInDom(thread));
111          return;
112        }
113
114        applySummaryTotal(summary, thread, counts[0]);
115      })
116      .catch(function () {
117        applySummaryTotal(summary, thread, countIssoCommentsInDom(thread));
118      });
119  }
120
121  function isIssoCommentHash(hash) {
122    return hash === 'kommentare' || /^isso-\d+$/.test(hash) || /^fediverse-/.test(hash) || /^webmention-/.test(hash);
123  }
124
125  function revealHiddenIssoComments(hash) {
126    var thread = document.getElementById('isso-thread');
127
128    if (!thread || !hash) {
129      return false;
130    }
131
132    var safety = 0;
133
134    while (!document.getElementById(hash) && safety < 100) {
135      var loader = thread.querySelector('a.isso-load-hidden');
136
137      if (!loader) {
138        break;
139      }
140
141      loader.click();
142      safety += 1;
143    }
144
145    return !!document.getElementById(hash);
146  }
147
148  function tryReachIssoHash(hash) {
149    revealHiddenIssoComments(hash);
150
151    return scrollToIssoHashTarget(hash);
152  }
153
154  function highlightIssoTarget(el) {
155    var prev = document.querySelector('.isso-target');
156
157    if (prev) {
158      prev.classList.remove('isso-target');
159    }
160
161    var wrapper = el.querySelector ? el.querySelector('.isso-text-wrapper') : null;
162
163    (wrapper || el).classList.add('isso-target');
164  }
165
166  function resolveIssoHashElement(hash) {
167    var target = document.getElementById(hash);
168
169    if (!target) {
170      return null;
171    }
172
173    if (/^isso-\d+$/.test(hash)) {
174      return target.classList.contains('isso-comment')
175        ? target
176        : (target.closest('.isso-comment') || target);
177    }
178
179    return target;
180  }
181
182  function scrollToIssoHashTarget(hash) {
183    if (!hash) {
184      return false;
185    }
186
187    var el = resolveIssoHashElement(hash);
188
189    if (!el) {
190      return false;
191    }
192
193    var rect = el.getBoundingClientRect();
194
195    if (rect.height === 0 && rect.width === 0) {
196      el = el.parentElement || el;
197    }
198
199    el.scrollIntoView({ behavior: 'auto', block: 'start' });
200    highlightIssoTarget(el);
201
202    return true;
203  }
204
205  function openCommentsDetails() {
206    var details = document.querySelector('.isso-wrap[data-section="comments"]');
207
208    if (!details) {
209      return;
210    }
211
212    details.open = true;
213
214    try {
215      localStorage.setItem('beilage-comments', 'true');
216    } catch (e) {
217      /* ignore */
218    }
219  }
220
221  function watchIssoHashAnchor() {
222    var hash = window.location.hash.replace(/^#/, '');
223
224    if (!isIssoCommentHash(hash)) {
225      return;
226    }
227
228    openCommentsDetails();
229
230    if (tryReachIssoHash(hash)) {
231      return;
232    }
233
234    if (!/^fediverse-/.test(hash) && !/^webmention-/.test(hash) && !/^isso-\d+$/.test(hash)) {
235      return;
236    }
237
238    var thread = document.getElementById('isso-thread');
239
240    if (!thread) {
241      return;
242    }
243
244    if (thread._issoHashStop) {
245      thread._issoHashStop();
246    }
247
248    var attempts = 0;
249    var stop = function () {
250      clearInterval(interval);
251      observer.disconnect();
252      thread._issoHashStop = null;
253    };
254
255    thread._issoHashStop = stop;
256
257    var observer = new MutationObserver(function () {
258      if (tryReachIssoHash(hash)) {
259        stop();
260      }
261    });
262
263    observer.observe(thread, { childList: true, subtree: true });
264
265    var interval = setInterval(function () {
266      if (tryReachIssoHash(hash) || ++attempts > 120) {
267        stop();
268      }
269    }, 250);
270  }
271
272  function bustIssoLatestCache() {
273    fetch('/api/isso-latest-cache-clear', {
274      method: 'GET',
275      credentials: 'same-origin',
276      keepalive: true,
277    }).catch(function () {
278      /* ignore */
279    });
280  }
281
282  function initIssoSummary() {
283    var thread = document.getElementById('isso-thread');
284    var summary = document.querySelector('[data-isso-summary]');
285
286    if (!thread || !summary) {
287      return;
288    }
289
290    thread._wirresFederatedCount = getFederatedCommentCount(summary, thread);
291    thread._wirresInstagramCount = getInstagramCommentCount(summary, thread);
292
293    var lastIssoCommentCount = countIssoCommentsInDom(thread);
294
295    var debouncedRefresh = function () {
296      clearTimeout(thread._issoSummaryTimer);
297      thread._issoSummaryTimer = setTimeout(refreshIssoSummary, 400);
298    };
299
300    var debouncedLatestCacheBust = function () {
301      clearTimeout(thread._issoLatestCacheTimer);
302      thread._issoLatestCacheTimer = setTimeout(function () {
303        var currentCount = countIssoCommentsInDom(thread);
304
305        if (currentCount !== lastIssoCommentCount) {
306          lastIssoCommentCount = currentCount;
307          bustIssoLatestCache();
308        }
309      }, 800);
310    };
311
312    var embed = document.querySelector('script[data-isso][src*="embed"]');
313
314    if (embed) {
315      embed.addEventListener('load', function () {
316        setTimeout(watchIssoHashAnchor, 600);
317      });
318    }
319
320    watchIssoHashAnchor();
321    window.addEventListener('hashchange', watchIssoHashAnchor);
322
323    new MutationObserver(function () {
324      debouncedRefresh();
325      debouncedLatestCacheBust();
326    }).observe(thread, {
327      childList: true,
328      subtree: true,
329    });
330  }
331
332  window.wirresRefreshIssoSummary = refreshIssoSummary;
333
334  if (document.readyState === 'loading') {
335    document.addEventListener('DOMContentLoaded', initIssoSummary);
336  } else {
337    initIssoSummary();
338  }
339})();

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.