PageSourceSearch

https://www.lawsociety.ie/UI/js/Blocks/ticker-block.js?v=RZLWQprDdIdnNhNr2bBl-vyerF1oIpfvqQG68QdCCHM

js lawsociety.ie collected 2026-10-02 02:56:35 UTC 7,332 bytes, 219 lines download raw bytes

1// Step-by-step ticker (one item at a time)
2(function () {
3    function initStepTicker(container) {
4        if (!container || container.__tickerInited) return;
5        container.__tickerInited = true;
6
7        var viewport = container.querySelector('.ticker__viewport');
8        var track = container.querySelector('.ticker__track');
9        if (!viewport || !track) return;
10
11        var items = Array.prototype.slice.call(track.querySelectorAll('.ticker__item'));
12        if (!items.length) return;
13
14        var pauseMs = parseInt(container.getAttribute('data-pause-ms') || '3000', 10);
15        var pps = parseFloat(container.getAttribute('data-speed-pps') || '120');
16        if (isNaN(pps) || pps <= 0) pps = 120;
17
18        var respectRMAttr = (container.getAttribute('data-respect-rm') || 'false').toLowerCase();
19        var respectRM = respectRMAttr === 'true';
20
21        var prefersReduced = false;
22        try { prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; } catch (e) { }
23        var autoRun = !(respectRM && prefersReduced);
24
25        // If only one item, just show it statically
26        if (items.length === 1) {
27            items[0].classList.add('ticker__item--active');
28            items[0].style.opacity = '1';
29            items[0].style.visibility = 'visible';
30            return;
31        }
32
33        var currentIndex = 0;
34        var pausedByUser = false;
35        var timerId = null;
36        var isAnimating = false;
37
38        // Function to show a specific item
39        function showItem(index) {
40            if (isAnimating) return;
41
42            // Hide all items
43            items.forEach(function (item) {
44                item.classList.remove('ticker__item--active');
45                item.style.opacity = '0';
46                item.style.visibility = 'hidden';
47            });
48
49            // Show the current item
50            if (items[index]) {
51                items[index].classList.add('ticker__item--active');
52                items[index].style.opacity = '1';
53                items[index].style.visibility = 'visible';
54            }
55
56            currentIndex = index;
57        }
58
59        // Function to transition to next item with fade effect
60        function transitionToNext() {
61            if (isAnimating) return;
62
63            isAnimating = true;
64
65            // Start fade out
66            if (items[currentIndex]) {
67                items[currentIndex].style.opacity = '0';
68            }
69
70            // After fade out, switch to next item and fade in
71            setTimeout(function () {
72                // Hide current item completely
73                if (items[currentIndex]) {
74                    items[currentIndex].classList.remove('ticker__item--active');
75                    items[currentIndex].style.visibility = 'hidden';
76                }
77
78                // Calculate next index
79                var nextIndex = (currentIndex + 1) % items.length;
80
81                // Show next item
82                if (items[nextIndex]) {
83                    items[nextIndex].classList.add('ticker__item--active');
84                    items[nextIndex].style.visibility = 'visible';
85                    items[nextIndex].style.opacity = '0';
86
87                    // Force reflow
88                    void items[nextIndex].offsetWidth;
89
90                    // Fade in
91                    items[nextIndex].style.opacity = '1';
92                }
93
94                currentIndex = nextIndex;
95                isAnimating = false;
96
97            }, 300); // Match the CSS transition time
98        }
99
100        function advance() {
101            if (!autoRun || pausedByUser || isAnimating) return;
102
103            transitionToNext();
104
105            if (autoRun && !pausedByUser) {
106                timerId = setTimeout(advance, pauseMs);
107            }
108        }
109
110        function start() {
111            stop();
112            showItem(0);
113            if (autoRun && items.length > 1) {
114                timerId = setTimeout(advance, pauseMs);
115            }
116        }
117
118        function stop() {
119            if (timerId) {
120                clearTimeout(timerId);
121                timerId = null;
122            }
123        }
124
125        // Pause on hover/focus
126        container.addEventListener('mouseenter', function () {
127            pausedByUser = true;
128            container.classList.add('ticker--paused');
129            stop();
130        });
131
132        container.addEventListener('mouseleave', function () {
133            pausedByUser = false;
134            container.classList.remove('ticker--paused');
135            if (autoRun && items.length > 1) {
136                timerId = setTimeout(advance, pauseMs);
137            }
138        });
139
140        container.addEventListener('focusin', function (e) {
141            if (container.contains(e.target)) {
142                pausedByUser = true;
143                container.classList.add('ticker--paused');
144                stop();
145            }
146        });
147
148        container.addEventListener('focusout', function (e) {
149            if (!container.contains(e.relatedTarget)) {
150                pausedByUser = false;
151                container.classList.remove('ticker--paused');
152                if (autoRun && items.length > 1) {
153                    timerId = setTimeout(advance, pauseMs);
154                }
155            }
156        });
157
158        // Handle image loading and text rendering
159        var imgs = track.querySelectorAll('img');
160        var pending = imgs.length;
161
162        function checkReady() {
163            if (--pending === 0) {
164                // Small delay to ensure text has rendered
165                setTimeout(function () {
166                    start();
167                }, 100);
168            }
169        }
170
171        if (pending > 0) {
172            imgs.forEach(function (img) {
173                if (img.complete) {
174                    checkReady();
175                } else {
176                    img.addEventListener('load', checkReady, { once: true });
177                    img.addEventListener('error', checkReady, { once: true });
178                }
179            });
180        } else {
181            // No images, but wait for text rendering
182            setTimeout(function () {
183                start();
184            }, 100);
185        }
186
187        // Initial setup
188        if (pending === 0) {
189            setTimeout(function () {
190                start();
191            }, 100);
192        }
193    }
194
195    function bootstrapRoot(root) {
196        (root || document).querySelectorAll('.ticker.ticker--step').forEach(initStepTicker);
197    }
198
199    // Run now, on DOM ready, and after full load
200    if (document.readyState !== 'loading') bootstrapRoot();
201    document.addEventListener('DOMContentLoaded', function () { bootstrapRoot(); });
202    window.addEventListener('load', function () { bootstrapRoot(); });
203
204    // MutationObserver for CMS editing
205    try {
206        var observer = new MutationObserver(function (muts) {
207            var needs = false;
208            for (var i = 0; i < muts.length; i++) {
209                var m = muts[i];
210                if (m.type === 'childList' && m.addedNodes && m.addedNodes.length) {
211                    needs = true;
212                    break;
213                }
214            }
215            if (needs) bootstrapRoot();
216        });
217        observer.observe(document.documentElement || document.body, { childList: true, subtree: true });
218    } catch (e) { /* no-op */ }
219})();

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.