1(() => { 2 'use strict' 3 4 var resultcount = 0; 5 var xhr; 6 7 const updatenotification = function() { 8 fetch(orbispatches.apiUri + '/update', { method: 'GET' }).then((response) => response.json()).then((data) => { 9 if(data.success && data.show_modal && !getCookie('update_' + data.cookie)) { 10 var modal = createModal({ 11 title: data.modal_title, 12 size: 'modal-lg', 13 closeBtn: true, 14 closeBtnText: "Ok", 15 bodyTemplate: [ 16 '<p class="text-muted">Published on ' + data.date + '</p>', 17 data.modal_text 18 ].join('') 19 }); 20 21 var updateModal = document.getElementById('dynmodal') 22 updateModal.addEventListener('hide.bs.modal', function (event) { 23 setCookie('update_' + data.cookie, '1', 9999); 24 }); 25 26 // Cleanup 27 var cookieArray = document.cookie.split(';'); 28 for(var i = 0; i < cookieArray.length; i++) { 29 var cookieName = cookieArray[i].trim(); 30 31 if(cookieName.startsWith('update_') && cookieName != 'update_' + data.cookie) { 32 document.cookie = cookieName +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 33 } 34 } 35 } 36 }); 37 } 38 39 const dynamicformhandler = async function() { 40 $('body').addEventListener('submit', async function(event) { 41 event.preventDefault(); 42 43 var targetElement = event.target || event.srcElement; 44 45 if(targetElement.hasAttribute('dynamicform')) { 46 var endpoint = targetElement.getAttribute('data-endpoint'); 47 var func = targetElement.getAttribute('data-func'); 48 49 var formData = new FormData(targetElement); 50 var json = {}; 51 52 formData.forEach(function(value, key) { 53 json[key] = value; 54 }); 55 56 for (var i = 0, len = targetElement.length; i < len; ++i) { 57 targetElement[i].disabled = true; 58 } 59 60 targetElement.insertAdjacentHTML('afterbegin', [ 61 '<div class="spinner position-absolute top-0 start-0 bottom-0 left-0 w-100" style="background: rgba(255, 255, 255, 0.5)">', 62 '<div class="d-flex justify-content-center align-items-center h-100">', 63 '<div class="spinner-border" role="status"></div>', 64 '</div>', 65 '</div>' 66 ].join('')); 67 68 var submitData = await httpPost(endpoint, json); 69 70 if(submitData) { 71 var response = submitData; 72 73 for (var i = 0, len = targetElement.length; i < len; ++i) { 74 targetElement[i].disabled = false; 75 } 76 77 targetElement.querySelector('.spinner').style.display = 'none'; 78 79 if (typeof func !== typeof undefined && func !== false) { 80 dynamicresponse[func](response, targetElement); 81 } else { 82 dynamicresponse['default'](response, targetElement); 83 } 84 } 85 } 86 }); 87 } 88 89 const dynamicmodalhandler = async function() { 90 if($('[dynamicmodal]')) { 91 $$('[dynamicmodal]').forEach(item => { 92 item.addEventListener('click', async function(event) { 93 event.preventDefault(); 94 95 var title = item.getAttribute('data-title'); 96 var size = item.getAttribute('data-size') ?? 'lg'; 97 var url = item.getAttribute('data-url'); 98 var params = item.getAttribute('data-params'); 99 100 createModal({ 101 title: title, 102 size: size ? 'modal-' + size : '', 103 bodyTemplate: loadingTemplate 104 }); 105 106 // Parameter processing
107 var requestParams = {}; 108 109 // Check if the modal requires any additional params to be send with the request 110 if(params) { 111 var paramObj = params.replace(/'/g, '"'); 112 paramObj = JSON.parse(paramObj); 113 114 for(var index in paramObj) { 115 requestParams[index] = paramObj[index]; 116 } 117 } 118 119 var requestParamsEncoded = encodeQueryData(requestParams); 120 121 var requestUrl = orbispatches.apiUri + '/data/' + url + '.php?' + requestParamsEncoded; 122 123 if(item.getAttribute('data-external')) { 124 requestUrl = url; 125 } 126 127 var submitData = await httpGet(requestUrl, false); 128 129 if(submitData) { 130 $('#modal-dyn').innerHTML = submitData; 131 } else { 132 createModalResponse('Something went wrong. Please try again.', 'danger'); 133 } 134 }); 135 }); 136 } 137 } 138 139 const searchformhandler = async function() { 140 if($('#search-form')) { 141 $('#search-form').addEventListener('submit', async function(event) { 142 event.preventDefault(); 143 144 var term = encodeURI($('#search-box').value); 145 146 if((isTitleIdValid(term) || isPublisherIdValid(term)) && resultcount > 0) { 147 window.location.href = '/' + term; 148 } else { 149 window.location.href = '/search?q=' + term + '&p=1'; 150 } 151 }); 152 } 153 } 154 155 const searchboxhandler = async function() { 156 if($('#search-box')) { 157 var autoCompleteHandler = new autoComplete({ 158 selector: '#search-box', 159 minChars: 2, 160 cache: false, 161 delay: 0, 162 offsetTop: 2, 163 noSuggestions: 'No results found.', 164 source: function (term, response) { 165 try { 166 xhr.abort(); 167 } catch (e) {} 168 169 xhr = nanoajax.ajax({ 170 url: orbispatches.apiUri + '/search?term=' + term 171 }, 172 function (code, res) { 173 var json = JSON.parse(res); 174 if (typeof json != "undefined") { 175 if (json.success && json.results) { 176 resultcount = json.results.length; 177 response(json.results); 178 } 179 } 180 } 181 ); 182 }, 183 renderItem: function(item, search) { 184 search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); 185 var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi"); 186 var name = item.name ? item.name.replace(re, "<span style='background: var(--autocomplete-highlight); color: #337197; border-radius: 5px;'>$1</span>") : '<i>Unknown</i>'; 187 188 if(item.titleid) { 189 return [ 190 '<a href="/' + item.titleid + '" data-val="' + item.titleid + '" class="autocomplete-suggestion">', 191 '<div class="d-flex">', 192 '<div class="icon flex-shrink-0" style="background:url(' + item.icon + ')"></div>', 193 '<div class="d-flex align-items-center text-truncate">', 194 '<div class="d-block w-100">', 195 '<div class="name mb-1 d-block text-truncate">' + name + '</div>', 196 '<div class="mt-2"><span class="px-2 py-1 border border-2 rounded me-2 bg-white">' + item.region + '</span><code>' + item.titleid + '</code></div>', 197 '</div>', 198 '</div>', 199 '</div>', 200 '</a>' 201 ].join(''); 202 } 203 204 if(item.publisherid) { 205 return [ 206 '<a href="/' + item.publisherid + '" data-val="' + item.publisherid + '" class="autocomplete-suggestion">', 207 '<div class="d-flex">', 208 '<div class="flex-shrink-0">', 209 '<div class="d-flex flex-shrink-0 align-items-center bg-white text-dark rounded border border-2 p-3 me-3 fst-italic">' + item.publisherid + '</div>', 210 '</div>', 211 '<div class="d-flex align-items-center text-truncate">', 212 '<div class="d-block w-100">', 213 '<div class="name mb-1 d-block text-truncate">' + name + '</div>', 214 '</div>', 215 '</div>', 216 '</div>', 217 '</div>' 218 ].join(''); 219 } 220 }, 221 onSelect: function(e, term, item) { 222 var submitEvent = new Event('submit', { 223 'bubbles' : true, 224 'cancelable' : true 225 }); 226 227 $('#search-form').addEventListener('submit', $('#search-form'), false); 228 $('#search-form').dispatchEvent(submitEvent); 229 } 230 }); 231 } 232 } 233 234 const searchcancelhandler = async function() { 235 $('#TitleSearch-close-btn').addEventListener('click', async function() { 236 const searchModal = bootstrap.Modal.getOrCreateInstance($('#searchModal')); 237 searchModal.hide(); 238 }); 239 240 document.addEventListener('keydown', function(event) { 241 if (event.ctrlKey && event.key === 's') { 242 event.preventDefault(); 243 244 const searchModal = bootstrap.Modal.getOrCreateInstance($('#searchModal')); 245 246 searchModal.show(); 247 $('#search-box').focus(); 248 } 249 }); 250 } 251 252 const searchtyperhandler = async function() { 253 var searchbox = $('#search-box'); 254 255 if(searchbox) { 256 searchbox.addEventListener('input', function() { 257 $('.TitleSearch-Lookup').style.display = (searchbox.value !== '' ? 'block' : 'none'); 258 $('#empty-search-placeholder').style.display = (searchbox.value == '' ? 'block' : 'none'); 259 }); 260 261 $('.TitleSearch-Lookup').addEventListener('click', async function() { 262 var submitEvent = new Event('submit', { 263 'bubbles' : true, 264 'cancelable' : true 265 }); 266 267 $('#search-form').addEventListener('submit', $('#search-form'), false); 268 $('#search-form').dispatchEvent(submitEvent); 269 }); 270 } 271 } 272 273 window.addEventListener('load', () => { 274 updatenotification(); 275 });
276 277 window.addEventListener('DOMContentLoaded', () => { 278 // Dynamic form / modal 279 dynamicformhandler(); 280 dynamicmodalhandler(); 281 282 // Search form 283 searchformhandler(); 284 searchboxhandler(); 285 searchcancelhandler(); 286 searchtyperhandler(); 287 }); 288})()
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.