PageSourceSearch

https://netsecurity.com/shared/news-and-blog.js?v=20260925-2

js netsecurity.com collected 2026-10-02 05:28:13 UTC 3,147 bytes, 78 lines download raw bytes

1/* News & blog: announcements open in a reader on the page (and by link: #news-<name>), the sticky bar follows the
2   section in view. Blog articles and topics link to netsecurity.com, where the blog itself still lives. */
3(function () {
4    'use strict';
5
6    const header = document.querySelector('.hdx');
7    const bar = document.querySelector('.nb-bar');
8    const dlg = document.querySelector('.nb-reader');
9
10    function measure() {
11        document.body.style.setProperty('--nb-header', (header ? header.getBoundingClientRect().height + Math.min(0, parseFloat(getComputedStyle(header).top) || 0) : 76) + 'px');
12    }
13
14    window.addEventListener('resize', measure);
15    measure();
16
17    /* ---- the bar marks the section in view ---- */
18    const tabs = Array.from(document.querySelectorAll('.nb-tabs a'));
19    const secs = tabs.map(function (a) { return document.querySelector(a.getAttribute('href')); });
20
21    function spy() {
22        const line = (bar ? bar.getBoundingClientRect().bottom : 0) + 60;
23        let cur = 0;
24
25        secs.forEach(function (s, i) { if (s && s.getBoundingClientRect().top <= line) cur = i; });
26
27        tabs.forEach(function (a, i) {
28            if (i === cur) a.setAttribute('aria-current', 'true');
29            else a.removeAttribute('aria-current');
30        });
31    }
32
33    window.addEventListener('scroll', spy, { passive: true });
34    spy();
35
36    /* ---- the reader ---- */
37    if (!dlg || typeof dlg.showModal !== 'function') return;
38    const body = dlg.querySelector('.nb-reader-body');
39    let back = null;
40
41    function open(name, remember) {
42        const t = document.getElementById('nb-a-' + name);
43
44        if (!t) return;
45        body.innerHTML = '';
46        body.appendChild(t.content.cloneNode(true));
47
48        const title = body.querySelector('.nb-r-title');
49
50        if (title) title.id = 'nb-reader-title';
51        if (window.PUI) body.querySelectorAll('[data-ic]').forEach(function (el) { el.innerHTML = window.PUI.icon(el.getAttribute('data-ic')); });
52        body.querySelectorAll('a[href^="http"]').forEach(function (a) { a.target = '_blank'; a.rel = 'noopener'; });
53        back = document.activeElement;
54        dlg.showModal();
55        body.scrollTop = 0;
56        if (remember) history.replaceState(null, '', location.pathname + location.search + '#news-' + name);
57    }
58
59    document.addEventListener('click', function (e) {
60        const o = e.target.closest('[data-open]');
61
62        if (!o || e.target.closest('a')) return;
63        e.preventDefault();
64        open(o.getAttribute('data-open'), true);
65    });
66
67    dlg.querySelector('.nb-x').addEventListener('click', function () { dlg.close(); });
68    dlg.addEventListener('click', function (e) { if (e.target === dlg) dlg.close(); });
69
70    dlg.addEventListener('close', function () {
71        if (/^#news-/.test(location.hash)) history.replaceState(null, '', location.pathname + location.search + '#news');
72        if (back && back.focus) back.focus({ preventScroll: true });
73    });
74
75    const m = location.hash.match(/^#news-([a-z0-9-]+)$/);
76
77    if (m) window.addEventListener('load', function () { open(m[1], false); });
78})();

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.