PageSourceSearch

https://www.ispazio.net/wp-content/themes/ispazio-theme/assets/js/shortcodes.js?x58667&ver=1790235968

js ispazio.net collected 2026-09-24 17:12:50 UTC 5,892 bytes, 139 lines download raw bytes

1/* iSpazio — Shortcodes JS
2 * Handles client-side behavior for inline shortcodes that need it.
3 *
4 * [video] lazy bootstrap:
5 *   <video data-isp-video="src.mp4" [data-isp-autoplay="1"]> renders with no
6 *   <source> until it enters the viewport. Then we attach <source> + load(),
7 *   and (if autoplay) start playback muted+inline. Saves the full-file
8 *   download triggered by preload="auto" + autoplay.
9 */
10(function () {
11    'use strict';
12
13    function initVideos(root) {
14        var nodes = (root || document).querySelectorAll('video[data-isp-video]');
15        if (!nodes.length) return;
16
17        var promote = function (v) {
18            if (v.dataset.ispVideoLoaded === '1') return;
19            v.dataset.ispVideoLoaded = '1';
20            var fig = v.closest('.isp-video');
21            if (fig) fig.setAttribute('data-isp-video-loading', '1');
22
23            var s = document.createElement('source');
24            s.src = v.dataset.ispVideo;
25            s.type = 'video/mp4';
26            v.appendChild(s);
27
28            var clear = function () { if (fig) fig.removeAttribute('data-isp-video-loading'); };
29            v.addEventListener('loadeddata', clear, { once: true });
30            v.addEventListener('error', clear, { once: true });
31
32            v.load();
33
34            if (v.dataset.ispAutoplay === '1') {
35                v.muted = true;
36                v.playsInline = true;
37                var p = v.play();
38                if (p && typeof p.catch === 'function') p.catch(function () {});
39            }
40        };
41
42        if (!('IntersectionObserver' in window)) {
43            // Old browsers: just promote on first user interaction.
44            nodes.forEach(function (v) {
45                var once = function () { promote(v); document.removeEventListener('scroll', once); };
46                document.addEventListener('scroll', once, { passive: true, once: true });
47            });
48            return;
49        }
50
51        var io = new IntersectionObserver(function (entries) {
52            entries.forEach(function (e) {
53                if (!e.isIntersecting) return;
54                promote(e.target);
55                io.unobserve(e.target);
56            });
57        }, { rootMargin: '300px 0px' });
58
59        nodes.forEach(function (v) { io.observe(v); });
60    }
61
62    // [video] modalità controls: overlay play grande + click-ovunque-per-avviare.
63    // Il pulsante .isp-video__play copre tutto il player: un click qualunque
64    // avvia la riproduzione come il play nativo. Quando il video è in play
65    // l'overlay si nasconde (pointer-events:none) e i controlli nativi tornano
66    // pienamente utilizzabili; alla pausa/fine l'overlay riappare.
67    function initOverlays(root) {
68        var figs = (root || document).querySelectorAll('.isp-video--controls');
69        Array.prototype.forEach.call(figs, function (fig) {
70            if (fig.dataset.ispOverlayInit === '1') return;
71            fig.dataset.ispOverlayInit = '1';
72            var v   = fig.querySelector('video');
73            var btn = fig.querySelector('.isp-video__play');
74            if (!v || !btn) return;
75
76            btn.addEventListener('click', function (e) {
77                e.preventDefault();
78                var p = v.play();
79                if (p && typeof p.catch === 'function') p.catch(function () {});
80            });
81
82            v.addEventListener('play',  function () { fig.classList.add('isp-video--playing'); });
83            v.addEventListener('pause', function () { fig.classList.remove('isp-video--playing'); });
84            v.addEventListener('ended', function () { fig.classList.remove('isp-video--playing'); });
85        });
86    }
87
88    // [ispazio_about_timeline] — anno espandibile/comprimibile col chevron.
89    function initHistory(root) {
90        var btns = (root || document).querySelectorAll('.isp-history__year');
91        Array.prototype.forEach.call(btns, function (btn) {
92            if (btn.dataset.ispHistoryInit === '1') return;
93            btn.dataset.ispHistoryInit = '1';
94            var group = btn.closest('.isp-history__group');
95            if (!group) return;
96            btn.addEventListener('click', function () {
97                var collapsed = group.classList.toggle('is-collapsed');
98                btn.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
99            });
100        });
101    }
102
103    /* [instagram]: la pagina /embed/ di Instagram comunica la propria altezza
104     * con un messaggio "MEASURE". La ascoltiamo per adattare il riquadro senza
105     * caricare embed.js di Meta. Un solo listener per pagina. */
106    function initInstagram(root) {
107        var frames = (root || document).querySelectorAll('.isp-ig__frame');
108        if (!frames.length || window.__ispIgMeasure) return;
109        window.__ispIgMeasure = true;
110
111        window.addEventListener('message', function (e) {
112            if (e.origin !== 'https://www.instagram.com') return;
113            var data = e.data;
114            if (typeof data === 'string') {
115                try { data = JSON.parse(data); } catch (err) { return; }
116            }
117            if (!data || String(data.type).toUpperCase() !== 'MEASURE') return;
118
119            var h = data.details && parseInt(data.details.height, 10);
120            if (!h || h < 200 || h > 3000) return;
121
122            var all = document.querySelectorAll('.isp-ig__frame');
123            for (var i = 0; i < all.length; i++) {
124                if (all[i].contentWindow === e.source && all[i].parentNode) {
125                    all[i].parentNode.style.setProperty('--isp-ig-h', h + 'px');
126                    return;
127                }
128            }
129        }, false);
130    }
131
132    function init(root) { initVideos(root); initOverlays(root); initHistory(root); initInstagram(root); }
133
134    if (document.readyState === 'loading') {
135        document.addEventListener('DOMContentLoaded', function () { init(); });
136    } else {
137        init();
138    }
139})();

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.