PageSourceSearch

https://www.ibelsa.com/wp-content/plugins/rw-anbietervergleich/assets/js/rw-vs-frontend.js?ver=1.3.5

js ibelsa.com collected 2026-09-24 12:32:02 UTC 6,685 bytes, 173 lines download raw bytes

1(() => {
2	const body = document.body;
3	let lastTrigger = null;
4	let lastFullscreenTrigger = null;
5
6	document.addEventListener('click', (event) => {
7		const open = event.target.closest('[data-rw-vs-open]');
8		if (open) {
9			const id = open.getAttribute('aria-controls');
10			const modal = id ? document.getElementById(id) : null;
11			if (!modal) return;
12			lastTrigger = open;
13			document.querySelectorAll('.ib-cmp-card.is-active').forEach((card) => card.classList.remove('is-active'));
14			open.classList.add('is-active');
15			modal.hidden = false;
16			body.classList.add('rw-vs-modal-open');
17			modal.querySelector('.ib-cmp-modal__close')?.focus();
18			return;
19		}
20
21		const close = event.target.closest('[data-rw-vs-close]');
22		if (close) {
23			closeModal(close.closest('.ib-cmp-modal'));
24			return;
25		}
26
27		const fullscreenOpen = event.target.closest('[data-rw-vs-fullscreen-open]');
28		if (fullscreenOpen) {
29			openFullscreen(fullscreenOpen);
30			return;
31		}
32
33		const fullscreenClose = event.target.closest('[data-rw-vs-fullscreen-close]');
34		if (fullscreenClose) {
35			closeFullscreen(fullscreenClose.closest('.ib-compare-fullscreen'));
36		}
37	});
38
39	document.addEventListener('click', (event) => {
40		const scrollButton = event.target.closest('[data-rw-vs-scroll]');
41		if (scrollButton) {
42			const wrap = scrollButton.closest('.ib-compare-all-wrap');
43			const area = wrap?.querySelector('[data-rw-vs-scroll-area]');
44			if (!area) return;
45			const direction = scrollButton.dataset.rwVsScroll === 'left' ? -1 : 1;
46			area.scrollBy({ left: direction * Math.max(320, area.clientWidth * 0.72), behavior: 'smooth' });
47			return;
48		}
49
50		const fullscreenArrow = event.target.closest('[data-rw-vs-fullscreen-scroll]');
51		if (fullscreenArrow) {
52			const modal = fullscreenArrow.closest('.ib-compare-fullscreen');
53			const area = modal?.querySelector('[data-rw-vs-fullscreen-area]');
54			if (!area) return;
55			const direction = fullscreenArrow.dataset.rwVsFullscreenScroll === 'left' ? -1 : 1;
56			area.scrollBy({ left: direction * Math.max(380, area.clientWidth * 0.66), behavior: 'smooth' });
57		}
58	});
59
60	document.addEventListener('scroll', (event) => {
61		const area = event.target.closest?.('[data-rw-vs-scroll-area]');
62		if (area) updateScrollButtons(area.closest('.ib-compare-all-wrap'));
63
64		const fullscreenArea = event.target.closest?.('[data-rw-vs-fullscreen-area]');
65		if (fullscreenArea) updateFullscreenButtons(fullscreenArea.closest('.ib-compare-fullscreen'));
66	}, true);
67
68	window.addEventListener('resize', () => {
69		document.querySelectorAll('.ib-compare-all-wrap').forEach(updateScrollButtons);
70		document.querySelectorAll('.ib-compare-fullscreen:not([hidden])').forEach(updateFullscreenButtons);
71	});
72
73	requestAnimationFrame(() => {
74		document.querySelectorAll('.ib-compare-all-wrap').forEach(updateScrollButtons);
75	});
76
77	document.addEventListener('keydown', (event) => {
78		if (event.key !== 'Escape') return;
79		const fullscreen = document.querySelector('.ib-compare-fullscreen:not([hidden])');
80		if (fullscreen) {
81			closeFullscreen(fullscreen);
82			return;
83		}
84		closeModal(document.querySelector('.ib-cmp-modal:not([hidden])'));
85	});
86
87	document.addEventListener('change', (event) => {
88		const input = event.target.closest('[data-rw-vs-toggle]');
89		if (!input) return;
90		const wrap = input.closest('.ib-compare-all-wrap');
91		if (!wrap) return;
92		const slug = input.dataset.rwVsToggle;
93		wrap.querySelectorAll(`[data-rw-vs-column="${CSS.escape(slug)}"]`).forEach((cell) => {
94			cell.hidden = !input.checked;
95		});
96		updateRows(wrap);
97		requestAnimationFrame(() => updateScrollButtons(wrap));
98	});
99
100	function openFullscreen(trigger) {
101		const id = trigger.getAttribute('aria-controls');
102		const modal = id ? document.getElementById(id) : null;
103		const sourceWrap = trigger.closest('.ib-compare-all-wrap');
104		const sourceTable = sourceWrap?.querySelector('.ib-compare--all');
105		const target = modal?.querySelector('[data-rw-vs-fullscreen-area]');
106		if (!modal || !sourceTable || !target) return;
107
108		const clone = sourceTable.cloneNode(true);
109		clone.classList.add('ib-compare--fullscreen');
110		target.replaceChildren(clone);
111		target.scrollLeft = 0;
112		target.scrollTop = 0;
113		lastFullscreenTrigger = trigger;
114		modal.hidden = false;
115		body.classList.add('rw-vs-modal-open', 'rw-vs-fullscreen-open');
116		modal.querySelector('[data-rw-vs-fullscreen-close]')?.focus();
117		requestAnimationFrame(() => updateFullscreenButtons(modal));
118	}
119
120	function closeFullscreen(modal) {
121		if (!modal) return;
122		modal.hidden = true;
123		modal.querySelector('[data-rw-vs-fullscreen-area]')?.replaceChildren();
124		body.classList.remove('rw-vs-fullscreen-open');
125		if (!document.querySelector('.ib-cmp-modal:not([hidden])')) body.classList.remove('rw-vs-modal-open');
126		lastFullscreenTrigger?.focus();
127		lastFullscreenTrigger = null;
128	}
129
130	function updateScrollButtons(wrap) {
131		if (!wrap) return;
132		const area = wrap.querySelector('[data-rw-vs-scroll-area]');
133		if (!area) return;
134		const max = Math.max(0, area.scrollWidth - area.clientWidth);
135		const left = wrap.querySelector('[data-rw-vs-scroll="left"]');
136		const right = wrap.querySelector('[data-rw-vs-scroll="right"]');
137		if (left) left.disabled = area.scrollLeft <= 2;
138		if (right) right.disabled = area.scrollLeft >= max - 2;
139	}
140
141	function updateFullscreenButtons(modal) {
142		if (!modal) return;
143		const area = modal.querySelector('[data-rw-vs-fullscreen-area]');
144		if (!area) return;
145		const max = Math.max(0, area.scrollWidth - area.clientWidth);
146		const left = modal.querySelector('[data-rw-vs-fullscreen-scroll="left"]');
147		const right = modal.querySelector('[data-rw-vs-fullscreen-scroll="right"]');
148		if (left) left.disabled = area.scrollLeft <= 2;
149		if (right) right.disabled = area.scrollLeft >= max - 2;
150	}
151
152	function updateRows(wrap) {
153		const enabled = [...wrap.querySelectorAll('[data-rw-vs-toggle]:checked')].map((input) => input.dataset.rwVsToggle);
154		wrap.querySelectorAll('tbody tr').forEach((row) => {
155			const referenceHasValue = row.dataset.referenceValue === '1';
156			const selectedHasValue = enabled.some((slug) => row.dataset[`value${toDatasetKey(slug)}`] === '1');
157			row.hidden = !referenceHasValue && !selectedHasValue;
158		});
159	}
160
161	function toDatasetKey(slug) {
162		return slug.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('');
163	}
164
165	function closeModal(modal) {
166		if (!modal) return;
167		modal.hidden = true;
168		if (!document.querySelector('.ib-compare-fullscreen:not([hidden])')) body.classList.remove('rw-vs-modal-open');
169		document.querySelectorAll('.ib-cmp-card.is-active').forEach((card) => card.classList.remove('is-active'));
170		lastTrigger?.focus();
171		lastTrigger = null;
172	}
173})();

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.