PageSourceSearch

https://dentalpodcast.org/wp-content/plugins/library-display/assets/js/shortcode.js?ver=1791090829

js dentalpodcast.org collected 2026-10-04 05:14:55 UTC 4,491 bytes, 177 lines download raw bytes

1(function() {
2	'use strict';
3
4	function normalizeText(value) {
5		return String(value || '').trim().toLowerCase();
6	}
7
8	function setDisplay(element, visible) {
9		if (!element) {
10			return;
11		}
12
13		element.style.display = visible ? '' : 'none';
14	}
15
16	function getOrCreateNoResults(root) {
17		const existing = root.querySelector('.libd-no-results');
18
19		if (existing) {
20			return existing;
21		}
22
23		const element = document.createElement('p');
24		element.className = 'libd-no-results';
25		element.textContent = root.dataset.notFound || '';
26		element.style.display = 'none';
27
28		root.appendChild(element);
29
30		return element;
31	}
32
33	function setActiveNav(navLinks, activeFilter) {
34		navLinks.forEach((link) => {
35			link.classList.toggle('libd-active', link.dataset.filter === activeFilter);
36		});
37	}
38
39	function getCountText(totalShown, isMulti, multiLabel, resultSingular, resultPlural) {
40		if (totalShown < 1) {
41			return '';
42		}
43
44		if (isMulti && multiLabel) {
45			return totalShown === 1
46				? `1 item in ${multiLabel}`
47				: `${totalShown} ${multiLabel}`;
48		}
49
50		return `${totalShown} ${totalShown === 1 ? resultSingular : resultPlural}`;
51	}
52
53	function initDirectory(root) {
54		if (!root || root.dataset.libdInit === '1') {
55			return;
56		}
57
58		root.dataset.libdInit = '1';
59
60		const searchInput = root.querySelector('.libd-search');
61		const clearBtn = root.querySelector('.libd-clear');
62		const countEl = root.querySelector('.libd-result-count');
63		const navLinks = Array.from(root.querySelectorAll('.libd-nav-link'));
64		const sections = Array.from(root.querySelectorAll('.libd-section'));
65		const noResults = getOrCreateNoResults(root);
66
67		if (!searchInput || !clearBtn || !countEl || !navLinks.length || !sections.length) {
68			return;
69		}
70
71		let activeFilter = 'all';
72		let query = '';
73
74		const resultSingular = root.dataset.resultSingular || 'item';
75		const resultPlural = root.dataset.resultPlural || 'items';
76		const multiLabel = root.dataset.multiLabel || '';
77		const isMulti = root.dataset.isMulti === '1';
78
79		function render() {
80			let totalShown = 0;
81			const normalizedQuery = normalizeText(query);
82
83			sections.forEach((section) => {
84				const sectionFilters = (section.dataset.filter || '').split(/\s+/).filter(Boolean);
85				const entries = Array.from(section.querySelectorAll('.libd-entry'));
86				let shownInSection = 0;
87
88				if (activeFilter !== 'all' && !sectionFilters.includes(activeFilter)) {
89					entries.forEach((entry) => setDisplay(entry, false));
90					setDisplay(section, false);
91					return;
92				}
93
94				entries.forEach((entry) => {
95					const titleEl = entry.querySelector('.libd-entry-title');
96					const title = normalizeText(titleEl ? titleEl.textContent : '');
97					const entryFilters = (entry.dataset.filter || '').split(/\s+/).filter(Boolean);
98					const matchesQuery = !normalizedQuery || title.includes(normalizedQuery);
99					const matchesFilter =
100						activeFilter === 'all' || entryFilters.includes(activeFilter);
101					const isVisible = matchesQuery && matchesFilter;
102
103					setDisplay(entry, isVisible);
104
105					if (isVisible) {
106						shownInSection++;
107					}
108				});
109
110				setDisplay(section, shownInSection > 0);
111				totalShown += shownInSection;
112			});
113
114			setDisplay(noResults, totalShown === 0);
115			countEl.textContent = getCountText(
116				totalShown,
117				isMulti,
118				multiLabel,
119				resultSingular,
120				resultPlural
121			);
122		}
123
124		navLinks.forEach((link) => {
125			link.addEventListener('click', (event) => {
126				event.preventDefault();
127
128				if (link.classList.contains('libd-empty')) {
129					return;
130				}
131
132				const clickedFilter = link.dataset.filter || 'all';
133
134				searchInput.value = '';
135				query = '';
136
137				if (activeFilter === clickedFilter && clickedFilter !== 'all') {
138					activeFilter = 'all';
139				} else {
140					activeFilter = clickedFilter;
141				}
142
143				setActiveNav(navLinks, activeFilter);
144				render();
145			});
146		});
147
148		searchInput.addEventListener('input', () => {
149			query = searchInput.value || '';
150			activeFilter = 'all';
151			setActiveNav(navLinks, activeFilter);
152			render();
153		});
154
155		clearBtn.addEventListener('click', () => {
156			searchInput.value = '';
157			query = '';
158			activeFilter = 'all';
159			setActiveNav(navLinks, activeFilter);
160			searchInput.focus();
161			render();
162		});
163
164		setActiveNav(navLinks, activeFilter);
165		render();
166	}
167
168	function init() {
169		document.querySelectorAll('.library-display').forEach(initDirectory);
170	}
171
172	if (document.readyState === 'loading') {
173		document.addEventListener('DOMContentLoaded', init);
174	} else {
175		init();
176	}
177})();

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.