PageSourceSearch

https://stlpartners.com/wp-content/plugins/stl-blocks/assets/js/quote-revolver.js?ver=0.19.4

js stlpartners.com collected 2026-10-02 02:24:54 UTC 3,609 bytes, 110 lines download raw bytes

1/**
2 * STL revolving quote square. Each .stl-quote-revolver auto-rotates through
3 * its quotes; pauses on hover; click a dot to jump.
4 */
5(function () {
6	'use strict';
7
8	function init(root) {
9		var dataEl = root.querySelector('.js-stl-quote-data');
10		if (!dataEl) return;
11		var quotes;
12		try { quotes = JSON.parse(dataEl.textContent); } catch (e) { return; }
13		if (!quotes || quotes.length < 2) return; // nothing to rotate
14
15		var rotateMs = parseInt(root.getAttribute('data-rotate-ms') || '6000', 10);
16		var stage = root.querySelector('.js-stl-quote-stage');
17		var qEl = root.querySelector('.js-stl-quote-text');
18		var nEl = root.querySelector('.js-stl-quote-name');
19		var rEl = root.querySelector('.js-stl-quote-role');
20		var dots = Array.prototype.slice.call(root.querySelectorAll('.js-stl-quote-dots .stl-quote-revolver__dot'));
21
22		var idx = 0, paused = false, timer = null;
23
24		// --- Height lock ---------------------------------------------------
25		// The quote text swaps in place, so quotes of different lengths would
26		// otherwise resize the revolver and stretch/shrink the whole case-
27		// studies grid on every rotation. We measure the tallest quote at the
28		// current width and pin the stage's min-height to it, so the block
29		// height stays constant no matter which quote is showing. Re-measured
30		// on resize because wrapping (and therefore height) changes with width.
31		function lockHeight() {
32			if (!stage) return;
33			var prevQ = qEl ? qEl.textContent : '';
34			var prevN = nEl ? nEl.textContent : '';
35			var prevR = rEl ? rEl.textContent : '';
36			stage.style.minHeight = '0px';
37			var maxH = 0;
38			quotes.forEach(function (q) {
39				if (qEl) qEl.textContent = q.q || '';
40				if (nEl) nEl.textContent = q.n || '';
41				if (rEl) rEl.textContent = q.r || '';
42				if (stage.scrollHeight > maxH) maxH = stage.scrollHeight;
43			});
44			if (qEl) qEl.textContent = prevQ;
45			if (nEl) nEl.textContent = prevN;
46			if (rEl) rEl.textContent = prevR;
47			stage.style.minHeight = maxH + 'px';
48		}
49
50		function paint() {
51			var q = quotes[idx];
52			stage.classList.add('is-out');
53			setTimeout(function () {
54				qEl.textContent = q.q || '';
55				nEl.textContent = q.n || '';
56				rEl.textContent = q.r || '';
57				root.style.background = q.bg || '#6b8fd6';
58				dots.forEach(function (d, i) { d.classList.toggle('is-active', i === idx); });
59				stage.classList.remove('is-out');
60			}, 450);
61		}
62
63		function tick() {
64			if (paused) return;
65			idx = (idx + 1) % quotes.length;
66			paint();
67		}
68
69		function start() {
70			stop();
71			timer = setInterval(tick, rotateMs);
72		}
73		function stop() { if (timer) { clearInterval(timer); timer = null; } }
74
75		root.addEventListener('mouseenter', function () { paused = true; });
76		root.addEventListener('mouseleave', function () { paused = false; });
77
78		dots.forEach(function (d) {
79			d.addEventListener('click', function () {
80				var i = parseInt(d.getAttribute('data-index'), 10);
81				if (isNaN(i) || i === idx) return;
82				idx = i;
83				paint();
84				start(); // reset timer
85			});
86		});
87
88		// Lock height now, again after full load (webfonts can change wrap
89		// metrics), and on resize (debounced).
90		lockHeight();
91		window.addEventListener('load', lockHeight);
92		var resizeTimer = null;
93		window.addEventListener('resize', function () {
94			if (resizeTimer) clearTimeout(resizeTimer);
95			resizeTimer = setTimeout(lockHeight, 150);
96		});
97
98		start();
99	}
100
101	function initAll() {
102		document.querySelectorAll('.stl-quote-revolver').forEach(init);
103	}
104
105	if (document.readyState === 'loading') {
106		document.addEventListener('DOMContentLoaded', initAll);
107	} else {
108		initAll();
109	}
110})();

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.