1(function () { 2 'use strict'; 3 4 var queryMap = { 5 name: 'dbl_name', 6 practice: 'dbl_practice', 7 office: 'dbl_office', 8 sort: 'dbl_sort', 9 industry: 'dbl_industry', 10 position: 'dbl_position', 11 veteran: 'dbl_veteran', 12 admission_state: 'dbl_state', 13 admission_court: 'dbl_court' 14 }; 15 16 function init(root) { 17 var form = root.querySelector('.dblps__form'); 18 var results = root.querySelector('.dblps__results'); 19 var clear = root.querySelector('.dblps__clear'); 20 var toggle = root.querySelector('.dblps__advanced-toggle'); 21 var advanced = root.querySelector('.dblps__advanced'); 22 var advancedCount = root.querySelector('.dblps__advanced-count'); 23 var nameInput = form.querySelector('[name="name"]'); 24 var debounceTimer = null; 25 var controller = null; 26 27 function getFilters() { 28 var data = new FormData(form); 29 var filters = {}; 30 Object.keys(queryMap).forEach(function (key) { 31 filters[key] = String(data.get(key) || '').trim(); 32 }); 33 return filters; 34 } 35 36 function advancedFilterCount(filters) { 37 return ['industry', 'position', 'veteran', 'admission_state', 'admission_court'].reduce(function (total, key) { 38 return total + (filters[key] ? 1 : 0); 39 }, 0); 40 } 41 42 function updateAdvancedCount(filters) { 43 if (!advancedCount) return; 44 var total = advancedFilterCount(filters); 45 advancedCount.textContent = total ? ' (' + total + ')' : ''; 46 } 47 48 function updateClearVisibility(filters) { 49 var active = Object.keys(filters).some(function (key) { 50 return key !== 'sort' && !!filters[key]; 51 }) || (filters.sort && filters.sort !== 'default'); 52 clear.classList.toggle('is-visible', !!active); 53 } 54 55 function syncUrl(filters) { 56 if (root.dataset.syncUrl !== '1' || !window.history || !window.URL) return; 57 var url = new URL(window.location.href); 58 Object.keys(queryMap).forEach(function (key) { 59 var queryKey = queryMap[key]; 60 if (filters[key]) { 61 url.searchParams.set(queryKey, filters[key]); 62 } else { 63 url.searchParams.delete(queryKey); 64 } 65 }); 66 window.history.replaceState({}, '', url.toString()); 67 } 68 69 function fetchResults() { 70 var filters = getFilters(); 71 updateAdvancedCount(filters); 72 updateClearVisibility(filters); 73 syncUrl(filters); 74 75 if (controller) controller.abort(); 76 controller = new AbortController(); 77 78 var url = new URL(DBLPS.endpoint, window.location.origin); 79 Object.keys(filters).forEach(function (key) { 80 if (filters[key]) url.searchParams.set(key, filters[key]); 81 }); 82 83 root.classList.add('is-loading'); 84 results.setAttribute('aria-busy', 'true'); 85 86 fetch(url.toString(), { 87 method: 'GET', 88 credentials: 'same-origin', 89 signal: controller.signal, 90 headers: { 'Accept': 'application/json' } 91 }) 92 .then(function (response) { 93 if (!response.ok) throw new Error('HTTP ' + response.status); 94 return response.json(); 95 }) 96 .then(function (payload) { 97 results.innerHTML = payload.html || ''; 98 }) 99 .catch(function (error) { 100 if (error.name === 'AbortError') return; 101 var status = root.querySelector('.dblps__status'); 102 if (status) status.setAttribute('data-error', DBLPS.error || 'Unable to update professionals.'); 103 }) 104 .finally(function () { 105 root.classList.remove('is-loading'); 106 results.setAttribute('aria-busy', 'false'); 107 }); 108 } 109 110 form.querySelectorAll('select').forEach(function (select) { 111 select.addEventListener('change', fetchResults); 112 }); 113 114 nameInput.addEventListener('input', function () { 115 window.clearTimeout(debounceTimer); 116 debounceTimer = window.setTimeout(fetchResults, 300); 117 }); 118 119 toggle.addEventListener('click', function () { 120 var isOpen = toggle.getAttribute('aria-expanded') === 'true'; 121 toggle.setAttribute('aria-expanded', isOpen ? 'false' : 'true'); 122 if (isOpen) { 123 advanced.hidden = true; 124 advanced.classList.remove('is-open'); 125 } else { 126 advanced.hidden = false;
127 window.requestAnimationFrame(function () { 128 advanced.classList.add('is-open'); 129 }); 130 } 131 }); 132 133 clear.addEventListener('click', function () { 134 form.reset(); 135 nameInput.value = ''; 136 fetchResults(); 137 }); 138 139 updateAdvancedCount(getFilters()); 140 updateClearVisibility(getFilters()); 141 } 142 143 function boot() { 144 document.querySelectorAll('.dblps').forEach(init); 145 } 146 147 if (document.readyState === 'loading') { 148 document.addEventListener('DOMContentLoaded', boot); 149 } else { 150 boot(); 151 } 152})();
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.