PageSourceSearch

https://www.iowaattorneygeneral.gov/system/blockeditor/websites/1/pages/plugins/before-after-slider/index.js

js iowaattorneygeneral.gov collected 2026-10-02 02:40:40 UTC 4,002 bytes, 150 lines download raw bytes

1
2export default {
3	name: "before-after-slider",
4	displayName: "Before/After Slider",
5	version: "1.0.2",
6	settings: {"startPosition":{"min":0,"unit":"%","max":100,"label":"Starting Position","step":1,"type":"range","default":40},"orientation":{"label":"Orientation","options":[{"label":"Horizontal","value":"horizontal"},{"label":"Vertical","value":"vertical"}],"type":"select","default":"horizontal"},"showLabels":{"label":"Show Labels","type":"boolean","default":true}},
7	
8	mount: function (element, options) {
9		const container = element.querySelector(".ba-container");
10		const slider = element.querySelector(".ba-slider");
11		const beforeDiv = element.querySelector(".ba-before");
12		const handle = element.querySelector(".ba-handle");
13
14		if (
15			!container ||
16			!slider ||
17			!beforeDiv ||
18			!handle
19		) {
20			return {};
21		}
22
23		const isVertical = options.orientation === "vertical";
24		const startPos = Number.isFinite(parseInt(options.startPosition)) ? parseInt(options.startPosition) : 40;
25
26		// Utility: pointer coords (mouse or touch)
27		const getPoint = (e) => {
28			if (
29				e.touches &&
30				e.touches.length
31			) {
32				return {
33					x: e.touches[0].clientX,
34					y: e.touches[0].clientY
35				};
36			}
37
38			return {
39				x: e.clientX,
40				y: e.clientY
41			};
42		};
43
44		// Apply clip based on percentage (0..100)
45		
46		const applyClip = (percent) => {
47			const p = Math.max(0, Math.min(100, percent));
48
49			if (isVertical) {
50				// Clip from bottom
51				const val = `inset(0 0 ${100 - p}% 0)`;
52
53				beforeDiv.style.clipPath = val;
54				beforeDiv.style.webkitClipPath = val;
55
56				slider.style.top = `${p}%`;
57			}
58			else {
59				// Clip from right
60				const val = `inset(0 ${100 - p}% 0 0)`;
61
62				beforeDiv.style.clipPath = val;
63				beforeDiv.style.webkitClipPath = val;
64
65				slider.style.left = `${p}%`;
66			}
67		};
68
69		// Initial position
70		applyClip(startPos);
71
72		// Labels visibility (defensive)
73		const labels = element.querySelectorAll(".ba-label-before, .ba-label-after");
74		const showLabels = options.showLabels === true || options.showLabels === "true";
75
76		labels.forEach(label => {
77			label.style.display = showLabels ? "block" : "none";
78		});
79
80		let isDragging = false;
81
82		const updateFromEvent = (e) => {
83			if (!isDragging) {
84				return;
85			}
86
87			const rect = container.getBoundingClientRect();
88			const pt = getPoint(e);
89			let position;
90
91			if (isVertical) {
92				// down -> bigger %
93				position = ((pt.y - rect.top) / rect.height) * 100;
94			}
95			else {
96				// right -> bigger %
97				position = ((pt.x - rect.left) / rect.width) * 100;
98			}
99
100			applyClip(position);
101
102			// Prevent scroll on touch while dragging
103			if (e.cancelable) {
104				e.preventDefault();
105			}
106		};
107
108		const startDrag = (e) => {
109			isDragging = true;
110
111			if (e.cancelable) {
112				e.preventDefault();
113			}
114
115			updateFromEvent(e);
116		};
117
118		const stopDrag = () => {
119			isDragging = false;
120		};
121
122		// Accessibility
123		element.setAttribute("role", "group");
124		element.setAttribute("aria-label", "Before/After Slider");
125
126		// Events
127		handle.addEventListener("mousedown", startDrag);
128		handle.addEventListener("touchstart", startDrag, { passive: false });
129
130		document.addEventListener("mousemove", updateFromEvent);
131		document.addEventListener("touchmove", updateFromEvent, { passive: false });
132		document.addEventListener("mouseup", stopDrag);
133		document.addEventListener("touchend", stopDrag, { passive: true });
134		document.addEventListener("touchcancel", stopDrag, { passive: true });
135
136		// Cleanup
137		return {
138			unmount: () => {
139				handle.removeEventListener("mousedown", startDrag);
140				handle.removeEventListener("touchstart", startDrag, { passive: false });
141
142				document.removeEventListener("mousemove", updateFromEvent);
143				document.removeEventListener("touchmove", updateFromEvent, { passive: false });
144				document.removeEventListener("mouseup", stopDrag);
145				document.removeEventListener("touchend", stopDrag, { passive: true });
146				document.removeEventListener("touchcancel", stopDrag, { passive: true });
147			}
148		};
149	}
150};

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.